天天看点

Gallery Server Pro ----用于分享相片,视频,音频及其他媒体的ASP.NET相册[Carol]

<a href="http://www.codeproject.com/aspnet/Gallery_Server_Pro/GalleryServerPro_source.zip" target="_blank">Gallery Server Pro下载</a>

Gallery Server Pro是一个完整,稳定的,用于分享相片,视频,音频及其他媒体的ASP.NET相册,这一文章展示了其整体的风格及主要特征.

导言

Gallery Server Pro是强大便捷的ASP.NET网络应用程序,它使你能够在网络上分享,处理相片,视频,音频及其他的文件.

.稳定,产品准备就绪

.可以使用任何浏览器将媒体文件整理到相册中,可以随意添加,编辑,删除,旋转,编排,复制以及移动.

.使用一键同步和ZIP下载功能可简便地添加成千上万的文件.缩略版和压缩版会自动被创制.

.强大的用户安全,具有灵活的每册粒度?

.与DotNetNuke及其他框架合为一体,以提供一个高级的媒体相册

.图片元数据抽取?支持以下格式: EXIF, XMP, tEXt, IFD, 以及 IPTC.

.搜寻功能询问标题,字母,文件名,以及图片元数据.

.图片上附带有自己的文本和(或)图片的水印

. AJAX更丰富的灵活的界面

. 便捷的基于网络的安装

. 用SQL Server 2000或更高的级别作为数据库.支持MSDE 2000 和SQL Server 2005 Express.

.使用 ASP.NET会员供应商,以便你能够融合?现有帐户,包括Active Directory.

.数据输入使用供应商模式,它允许使用其他的数据库例如MySQL, MS Access, 或 Oracle来代替SQL Server.

.托管代码全部用C# and ASP.NET 2.0写.

.在开放源码GNU General Public License下发放源代码.

.所有的网页目标XHTML 1.0 Strict 和 CSS 2.1标准来确保兼容性的最大化.

背景

这一项目源于2002年我想把照片放到网络上进行分享的欲望.我想我的照片保留在我自己的服务器上,而不是其他人的服务器上,如EasyShare或Shutterfly的.由于那时没有可供选择的免费解决方案,所以就自己写了.

2006年1月我向世界推出了第一版,反响非常好, 下载次数超过了30,000次.2006年及2007年大多数时间我都在研究第二版, 在使用新的ASP.NET 2.0特征的组中重新写代码.

它包括了ASP.NET的Membership, Roles, Profiles, generics,the data provider model,以及几个著名的设计模式(strategy, iterator, factory, template method, and composite)

在这篇文章中,我将展示Gallery Server Pro的整体设计及主要特点.如果想知道更多,这里几个主题会有帮助:

.运用网络相册来分享相片,视频,音频及其他文件.

.使用了ASP.NET的Membership, Roles and Profile API

.使用综合设计模式来无限处理等级关系,一般是媒体物和相册,但它也应用于雇员/上司关系, 条例的材料,资料/目录关系及其他相似的结构项目.

.何时及如何来使用策略设计模式.

.在ASP.NET 2.0下使用数据提供模式.

.运用灵活的技术把明显的HTML提交到基于浏览器类型及要提交的对象类型的浏览器

.运用 .NET 2.0技术和新的.NET 3.0的WPF从图片中截取元数据

<b>使用</b><b>Gallery Server Pro</b>

Gallery Server Pro是一个完全功能性及稳定性的用于产品使用的网络应用程序.

2. 运用Internet Information Services (IIS) Manager来配置目录作为web应用程序. 保证这一应用在ASP.NET 2.0下运行.

3. 如果使用早于IIS 7的IIS版本,确保错误的文件设置到default.aspx. IIS 7用户可以跳过这一步.

4. 使用Windows Explorer将"modify" <b>config</b> 和<b>mediaobjects</b>目录的权限应用到IIS用户帐号。

5. 使用SQL管理工具如SQL Management Studio (SQL Server 2005)或 SQL Enterprise Manager (SQL Server 2000)来创建一个新的空的数据库.

7. 按照安装向导的步骤进行安装.完成后,你就可以使用Gallery Server Pro了.

Gallery Server Pro储存了媒体,如相册中的照片,视频,音频和文件等.这些文件和相册被储存在一个名为<b>mediaobjects</b>的在网络应用下的目录中(它可以在网络服务器上任意改变地址).一个相册只是一个目录,所以储存一个名为Vacation Photos的相册与目录的名字非常相似.

要添加媒体物有两个重要的技巧:

1. 上传一个包括媒体文件的ZIP文件. 如果这一ZIP文件包含目录,那它就转变为相册.

2. 将你的媒体文件复制到媒体目录中, 然后在Gallery Server Pro中启动同步?.

添加媒体物时,会发生以下步骤:

1. 文件保存到媒体物目录中.(如果通过同步技术来添加媒体物的话,这一步骤就已经完成了)

2. 缩略照片被创建并保存到硬盘.

3. 图片,压缩的宽带版本?被创建,元数据,如照相机模型和快门速度就被摘取了.

4. 数据库里将添加一个记录来代表这一媒体物.

媒体物通过HTTP处理器流向浏览器.下面您可以看到一张照片及一段视频正在被演示.如果水印有效的话,水印会在照片及视频上传前被添到有记忆版本的照片上.

如果你点击媒体物上方的视图元数据工具栏,就会弹出一个DIV窗口来演示图象的元数据,就如以下所示:

<a href="http://www.cnblogs.com/images/cnblogs_com/dotLive/WindowsLiveWriter/GalleryServerProASP.NETCarol_12D27/clip_image003_2.jpg"></a>

默认状态下每个人都可以浏览这个媒体物,但是你必须登陆来修改相册或媒体物。授权修改数据由相册的许可的类型?来配置。比如你可以建立用户<b>Soren</b>使其允许修改相册<b>Soren's photos</b><b>。</b>另外一个用户<b>Margaret</b>可以被编辑允许修改相册<b>Margaret's photos</b><b>。</b>每个用户都可以管理自己的相册,但不能编辑在他们域名之外的相册。

<b>解决方案架构</b><b></b>

这一下载的Visual Studio解决方案包括十个项目。

<b>项目名字</b><b> </b>

<b></b>

<b>描述</b>

gsweb

UI layer - ASP.NET 2.0 网络应用.

TIS.GSP.WebControls

包括用于网络应用的客户定制服务控制

TIS.GSP.Business

商务层逻辑

TIS.GSP.Provider

数据供应者。界定了数据层必须遵循的合同

TIS.GSP.Business.Interfaces

界定了在这个方案中使用的所有接口

TIS.GSP.ErrorHandler

提供了错误处理的支持

TIS.GSP.Configuration

提供了读/写程序进入储存于配置文件galleryserverpro.config的设置

TIS.GSP.Business.Wpf

通过截取能够在.NET 3.0. 中运用的新的WPF级来提供升级的图象元数据。当不在.NET 3.0时,就包含在一个分离的项目中,通过某种优雅降解的方式的反应来引用。???

TIS.GSP.Data

数据层逻辑。提供读/写进入到储存在SQL服务器的数据

TracingTools

提供追查的支持

<b>用户管理和安全</b>

<b>媒体,相册及其组合模式</b><b></b>

每一媒体(包括照片,视频等)都储存于相册中。相册可以放在另一个相册中,无层级

数量的限制。类似资料和目录在硬盘上储存。

相册和媒体物有许多共同点。他们都有例如这样的属性:Id, Title, DateAdded,及FullPhysicalPath;他们也有同样的方法,如 Save, Delete, Copy, Remove, and ValidateTitle.这是使用合成模式的理想环境,在这一环境中,常见功能被定义在基础物体中?。首先来界定两个接口 IGalleryObject 和IAlbum:

<a href="http://www.cnblogs.com/images/cnblogs_com/dotLive/WindowsLiveWriter/GalleryServerProASP.NETCarol_12D27/clip_image001%5B1%5D.jpg"></a>

IAlbum接口继承了IGalleryObject,随后又添加了用于相册的特定的一种方法和一些属性。然后创造了抽象基本类?GalleryObject。它使用了IGalleryObject接口,并且提供了相似于相册和媒体物的默认行为。比如,以下是Title属性:

既然常见功能被定义在抽象基本类中,我可以创建具体的类来代表相册,图象,视频,音频,以及其他的媒体物:

<a href="http://www.cnblogs.com/images/cnblogs_com/dotLive/WindowsLiveWriter/GalleryServerProASP.NETCarol_12D27/clip_image001%5B3%5D.jpg"></a>

运用这一方法,重复代码将极少出现,结构具有可维护性,并且使用方便。比如,当Gallery Server Pro想要为相册里的所有物体展示标题及缩略图时,有可能出现任何子相册,图片,视频,音频以及其他文件的组合。不过我不必担心所有不同的类和about casting问题。我所需要的只是以下代码:

完美,不是吗? 但是当两类物体间的功能存在细微的差别时会发生什么?例如,Gallery Server Pro强制要求一个相册的标题最大长度为200个字符,一个媒体物(图片,音频等)的标题最大长度为1000个字符。两类物体都需要Title属性, 但是验证却是不同的。 那是否意味着我们必须把Title 属性从基本类中移除,把它放到衍生类中? 不是的!参照我们之前看的代码中对于Title的属性界定,注意在设置中有一个对ValidateTitle 的call。以下是 ValidateTitle 在GalleryObject类中的样子:

这一程序是虚拟的,如果有必要,允许衍生层级凌驾于它之上。实际上,这正是Album 层所做的:

最终结果是在基层里有一个基础的执行为大多数案例提供功能,相册特定的代码包括在Album层级中。没有任何复制的代码,逻辑被完美地包裹。颇为完美!

<b>使用策略模式用以持续的数据储存</b><b></b>

我们刚刚看了当要改变其行为时如何在基本类中越过一种方法。当要保存相册及媒体物到数据库时我原本可以做一些类似的。在GalleryObject 层中的Save方法本可以被界定为虚拟的,我也原本可以在衍生类中越过这一方法。但是由于Image, Video, Audio, 和GenericMediaObject类都代表了被储存在同一个表里的物体(如媒体物),那可能意味着在所有四个类中写同样的代码,除了Album类。

我可以在GalleryObject类中通过为Save法提供一个默认操作来消除复制代码问题。在那个方法中,我保存到媒体物表格,然后依靠Album类来越过这一行为,很像我们对ValidateTitle的操作。然而这是把大量不真正属于那里的行为放到基本类中。我们必须将基本类限制于仅包含适用于ALL衍生物的状态和行为。

你也许会争论:我为ValidateTitle方法提供默认操作,在Album类中越过它时,我违反了这一原则。完全正确。以下是我的自圆其说:在每个衍生类中操作标题验证会创造不可取的复制代码,然后运用策略模式来重构它等于是矫枉过正。这些不是硬性规定。建构一个运用就如科学那样有技术性,你必须权衡每一步的正反意见。

回到我们对于持续的数据储存的挑战中,我想到的方法是用策略模式去包裹?行为。首先,界定接口ISaveBehavior:

然后我写了操作这一接口的两个类:AlbumSaveBehavior以及MediaObjectSaveBehavior.这一保存方法小心地将物体保留到硬盘和数据库。比如,以下是AlbumSaveBehavior的save方法:

注意这里有对PersistToFileSystemStore的需求,它是一个私人方法用以确保这个相册存在对应的目录。随后也有对Provider 类的Album_Save方法的需求,它坚持把数据保存到SQL 服务器的gs_Album表。如果你使用数据提供而不是默认的SqlDataProvider,那这一方法就代表了那个服务。我们将在下文中讨论数据供应。

好了,把数据储存到数据库我们有两个类——一个用于储存相册,一个用于储存媒体物。我们该怎样从GalleryObject基本类中引用合适的Save方法呢?

回忆一下,GalleryObject类是抽象的,所以它永远不能被例示出来。但是我们可以用Album, Image, Video, Audio, 或 GenericMediaObject类来具体示例。每个层的建构者指定了合适的储存行为。例如,在Album类中我们有:

GetAlbumSaveBehavior方法刚刚回到了AlbumSaveBehavior类的一个例子:

GalleryObject 类的SaveBehavior属性是ISaveBehavior类型。既然两个类都运用这个接口,我们可以指定任何一个层的例子到这一属性。

GalleryObject 类中Save方法在SaveBehavior属性中简单地叫Save方法。我们不清楚这一属性是AlbumSaveBehavior 或MediaObjectSaveBehavior的例子,但这无关紧要。最重要的是每一类都知道如何来保存其设计的物体。

这是一个运用策略模式的例子。具体而言,策略模式就是被包裹以及能够相互转变的系。在我们的例子中,我们有两种保存的行为,它们可以自我包含而且都可以被指定到同一个属性(可相互改变)。它是一个有力的模式,也有许多用处。

<b>向视频,图片,音频及更多提供</b><b>HTML</b>

由于浏览器都能识别&lt;img&gt;标签,所以在网页浏览器上展示图片是容易的。但是该怎样操作一个同样包括视频,音频以及其他例如Adobe PDF 或 Microsoft Word 资料的gallery呢?浏览器本身是不能展示任何视频和音频或天然地展示任何资料的,除了一些基本类型,像HTML, TXT以及可能 XML。这些物体的类型需要plug-ins,如果有的话,你也不可能对到底是什么plug-ins安装在用户的浏览器中作任何猜想。而且Gallery Server Pro是灵活的,这样管理者就能定制由提供的Gallery Server Pro HTML结果。例如,一些用户更喜欢视频资料有&lt;object&gt;标签,这样就可以通过XHTML校验,但其他人也许喜欢&lt;embed&gt;标签用以最大的背景兼容。最后,不同的浏览器需要不同的句法,新版的浏览器不断被开发,有可能会突破现在所运作的。

这一解决方案是使用储存在配置资料的HTML模版和由ASP.NET提供的自动浏览两者的结合。配置资料galleryserverpro.config(储存在config directory)包括用以每个主要的媒体物类型的HTML模版。例如,为一个图片提供HTML是非常直接的。这是galleryserverpro.config的相关输入:

这一mediaObject标签规定了内标签运用于image/* MIME 类型。asterisk (*)意味着它将匹配所有的图片,如image/jpg, image/jpeg, 和 image/gif。现在让我们进一步来看一下浏览器标签中htmlOutput属性中有什么:

注意:在配置资料&lt;, &gt;和htmlOutput属性中的字母都被遗漏了&amp;lt;, &amp;gt; and &amp;quot;但我在这里省略是为了读起来更加简便。

环绕在&lt;img&gt;标签周围四个&lt;div&gt;标签用以支持在每个图片周围出现的下降阴影和边界。但是在括号里的东西是什么,就如{MediaObjectUrl}?那些是在运行时间被动态生成的内容所代替的placeholders。比如,{Height}被图片的高度所替代。在Administrator's Guide中能找到这些placeholders的完整清单和描述。

当Gallery Server Pro使用上述的模板向浏览器提供一个图片,它以类似下面的东西结束:

如果愿意,你可以稍微调整一下这个模板来改变如何提供&lt;img&gt;标签。比如,你想使用宽度和高度属性而不是风格属性,请将配置资料更新到如下:

图片提供是非常直接的,如果我们所做的完全只是展示图片,那在此展示的技术就有点小题大做了。但一旦我们接触更加复杂的媒体类型它就变得有用了。例如,让我们来看一下galleryserverpro.config的描述视频是怎样提供的相关部分:

<b>Collapse</b>

注意这里有两个mediaObject元――一个用以规定MIME 类型 video/*,另一个规定video/quicktime。在video/* 下的HTML模板处理提供视频的所有通用个案。由于第二个元需要不同的HTML,因此它用以处理QuickTime视频的更多具体案例HTML。比如,如果AVI资料需要定制HTML,你可以添加其他的mediaObject元。

这两个元为默认浏览器明确了一个HTML,为IE明确了另一个HTML。如果仔细看一下HTML模板,你会发现它们是很相似的,除了一个明确AutoStartMediaObjectInt ,而另一个明确AutoStartMediaObjectText。那是因为IE需要autostart参数作为文本,像"true" 或 "false",而其他的浏览器需要一个数值(1 for true, 0 for false)。

比如你发现由于HTML 的非兼容性,Safari浏览器不能正常运作,你可以添加一个浏览器元id="safari"。然后用Safari要求的句法添加HTML模板,这样就完成了。Gallery Server Pro 和ASP.NET自动地辨认浏览器类型然后发送正确的HTML。

<b>数据供应商模式</b><b></b>

ASP.NET 2.0的一个最新特征就是供应商模式。在Gallery Server Pro中,我曾经用供应商模式将用以读写资料的API界定到数据库。只要那里写有供应商程序,你就可以使用数据库的任何资源。Gallery Server Pro 2.0包括SqlDataProvider,允许其与SQL服务器进行互动。还可以写其他的使用MySQL, Oracle, Microsoft Access,或者甚至是 XML 资料作为数据库的供应商。

下面的图表演示了SqlDataProvider类 和 DataProvider类,即使名字听上去像官方的.NET Framework类,这些是我特别为Gallery Server Pro而写的。DataProvider是抽象的继承于Microsoft .NET Framework System.Configuration.Provider.ProviderBase的类。它不包括任何的行为;它只是界定了必须用"real"数据供应商来操作的方法,在这个案子中就是SqlDataProvider。在Gallery Server Pro中所有的数据输入都通过SqlDataProvider中的其中一个方法(除非用户帐户功能通过其他的供应商--membership, roles, 及 profile)。

<a href="http://www.cnblogs.com/images/cnblogs_com/dotLive/WindowsLiveWriter/GalleryServerProASP.NETCarol_12D27/clip_image001%5B5%5D.jpg"></a>

要用另外的如MySQL, Oracle, Microsoft Access或其他的数据库,写一个新的继承DataProvider抽象基本类的类。你可以在一个新的项目中做,也可以通过在TIS.GSP.Data项目中添加一个新的类。如果你用例如Visual Studio的工具,它会自动界定所有必须要被执行的方法。比如,以下是用以删除一个相册所用方法的框架:

当某个相册需要被删除时Gallery Server Pro会呼叫这个方法。就如这个服务器供应商一样,写一个代码用以从你的数据库中删除相册记录是你的工作。怎样做就由你来定。

注意:参照SqlDataProvider类中的代码用以确保你提供相似的行为。比如,在删除一个相册的时候,SqlDataProvider类执行一个已存储的程序来递归删除这一特定相册的所有子相册。你的服务器供应商应相似操作。

一旦你已经操作了所有的方法并且编写好了代码,你就准备好配置Gallery Server Pro来使用你的供应商。将包含在你供应商内部的dll复制到Gallery Server Pro网页应用的bin directory。更新galleryserverpro.config的数据供应商区域。比如,如果你的供应商位于一个名为OracleDataProvider的类中,那一类位于一个名为GalleryServerPro.Data.Oracle.dll 的集合中,数据供应商区域将类似如下:

<b>图片元数据提取</b><b></b>

最长见为JPGs的图片资料能够包括元数据,例如照相机模式以及快门速度。而且,像Vista's Photo Gallery的应用允许用户添加关键词,标题,评级以及更多。Gallery Server Pro能够用下列任何一种形式来截取数据:EXIF, XMP, TEXT, IFD, 以及IPTC。

.NET 3.0中System.Windows.Media.Imaging 名字空间的介绍提供了一种先进的提取元数据的方法,包括获取之前不能输入的资料的能力――特别是标题和关键词。

因此现在有两种方法从图片中获取元数据――.NET 2.0 方式以及 .NET 3.0 方式。即使.NET 3.0技术更优一点,我想让Gallery Server Pro在一个未安装.NET 3.0的系统中工作。

结果,提取元数据运用了以下步骤:

1. 如果.NET 3.0安装在网络服务器中,System.Windows.Media.Imaging namespace??中使用BitmapMetadata类来截取尽可能多的meta数据到一个名为GalleryObjectMetadataItemCollection的custom collection???

2. 将图片Instantiate到 System.Imaging.Image目标。使用PropertyItems属性来截取尽可能多的metadata。对于每个metadata(如切换速度),将其添加到GalleryObjectMetadataItemCollection,但只有当它没有在步骤1中被添加过才可以。

换而言之,使用两种技术来提取同一个元数据,我们就使用.NET 3.0方法而舍弃.NET 2.0方法。

提取元数据数据的逻辑隐藏在业务层类MediaObjectMetadataExtractor中。当图片被添加到相册中时,以下的代码提取于GalleryServerPro.Business.Image构造:

变化的imageFile是 System.IO.FileInfo指代图片的例子。MetadataItems属性是GalleryObjectMetadataItemCollection。一旦元数据被提取以及被保存,你可以轻松地遍历项目并获取the name/value pairs:

<b>总结</b><b></b>

这是对用于Gallery Server Pro 的构驾级和编程技术的一个简单介绍。请自便下载源代码,以对您自己的项目有所帮助。

本文转自 lu xu 博客园博客,原文链接: http://www.cnblogs.com/dotLive/archive/2007/11/27/974733.html  ,如需转载请自行联系原作者