使用 DotNetAge 在 30 分钟内提升 ASP.NET MVC MUSIC STORE 的可用性
使用 DotNetAge 在几分钟内升级 ASP.NET Mvc Music Store,添加小部件和安全功能。
引言
MVC Music Store 是一个基于 ASP.NET MVC 2 构建的教程应用程序。它是一个轻量级的示例商店,用于在线销售专辑,演示了 ASP.NET MVC 2 的生产力特性和通过 Entity Framework 4 进行数据访问。当我们拿到 MVC Music Store 的源代码时,会发现它太简单了,而且外观非常糟糕。因此,我将使用另一个 MVC 平台来升级 MVC Music Store,使其外观漂亮,并提高可用性、安全性和可定制性。
背景
ASP.NET MVC Music Store 只是 MVC 2 的一个示例。我们想用少量代码为它添加以下功能:
- 运行时创建/编辑页面
- 支持页面上的小部件
- 支持每页的 RSS & Atom
- 支持主题并随时更改主题,使 Music Store 应用程序外观精美
- 支持类似 WordPress 的内容发布功能
- 支持论坛
- 文件管理
- 操作安全管理
- 用户管理
- 角色管理
首先,从 Codeplex 下载 MVC Music Store 应用程序 http://mvcmusicstore.codeplex.com/,然后在您的 VS.NET 扩展管理器中下载/安装 DotNetAge 项目。
合并项目文件
创建一个新的 DotNetAge 项目

合并 ASP.NET MVC MUSIC STORE 项目文件
- 合并Web.Config。
- 将连接字符串配置从 Music Store 复制到 DNA web.config 文件。
- 复制页面部分的命名空间设置。
- 将MvcMusicStore.mdf 数据库文件复制到 DotNetAge 项目的App_Data 文件夹。
- 复制所有控制器类文件,排除AccountController.cs、HomeController.cs,因为 DotNetAge 已经有了这些类,它们不适用于 DotNetAge。
- 更新AssemblyInfo.cs 文件。(修改版本号以启用小部件自动发现。)
- 将所有视图文件(排除Account 和Home 文件夹)复制到 DotNetAge 的Views 文件夹。
运行和设置项目数据
合并项目文件后,按“F5”运行应用程序,并使用“administrator”(密码:“administrator”)登录 DotNetAge。然后选择“SiteTools – > Console”打开网站设置。
创建小部件
现在回头看 ASP.NET MVC Music Store 应用程序,找出需要重构的 Action。
- 在许多页面中,我们发现 `GenreMenu` 在任何地方都使用了多次。实际上,它是一个数据驱动的导航菜单。在 ASP.NET Music Store 应用程序中,它是 `static` 的,看起来很糟糕!我们可以为这个菜单创建一个小部件,使其看起来不错,并允许管理员/创建者在不接触任何代码的情况下将其放置在任何页面上。
- 然后在页面底部有一个用于推广的专辑列表,我们可以将其放置在每个页面上,并通过运行时设置来控制专辑显示数量。
GenreMenuWidget
`GenreMenu` 是一个 Action,包含在StoreController.cs 中。我们向此 Action 添加 `WidgetAttribute` 并指定小部件标题“`GenreMenu`”,并指定该小部件所属的类别选项卡“`MusicStore`”。

完成!我们可以在“`MusicStore`”选项卡中的 `WidgetExplorer` 中找到此小部件。
TopSellingAlbumsWidget
你还记得我们没有将HomeController.cs 复制到 DotNetAge 吗?在 ASP.NET `MusicStore` 项目中,`HomeController` 有一个名为“`GetTopSellingAlbums`”的 `private` 方法。此方法有一个参数,允许用户指定返回多少张专辑。但在 Index Action 中是硬编码的。
将 `GetTopSellingAlbums` 和 `Index` 方法复制到 `DNAMusicStore` 项目的 `StoreController` 中,并将 Index Action 方法重命名为“`TopSellingAlbums`”。像我们为 `GenreMenuWidget` 所做的那样,在 `TopSellingAlbums` Action 上添加 `WidgetAttribute`。
我们希望用户能够在运行时设置返回的专辑数量,因此在 Action 上添加 `PropertyAttribute` 来指定 Count 作为用户偏好,并添加一个与用户偏好同名的参数(在运行时,DotNetAge Widget Engine 会自动将用户偏好值匹配到此参数)。

我们需要一个用户偏好设置面板,允许用户在运行时设置显示数量。右键单击 `TopSellingAlbums` 并单击“Add View”,然后放置如下代码:
我们使用 `WidgetViewUserControl` 而不是 `ViewUserControl`,因为 `WidgetViewUserControl` 包含了 Widget 实例数据以及我们运行时控制小部件所需的所有其他方法和属性。
看这段代码
Ajax.RenderAutoSettingForm(PropertyDescriptors,IDPrefix,IsDesignMode
这将自动生成一个设置表单,用于设置我们在 Widget Action 中指定的用户偏好。
最后,使用 `Html.StartupScripts` 来渲染此 Widget 的脚本。
按“F5”运行项目并以管理员身份登录,然后选择“SiteTools->Design this page – >Add Content”
我们将看到一个新的“`MusicStore`”选项卡已被添加。在 MusicStore 选项卡中包含两个小部件“`GenreMenu`”和“`TopSellingAlbums`”。单击图标,它将显示一个预览小部件的对话框。

现在我们将小部件添加到页面上,看看 DNAMusicStore 和 ASP.NET MusicStore 有什么区别。
我们可以在主页上放置 ImageWidget、Flash widget 或任何我们想要的小部件,并且您可以将 `GenreMenu` 移动到另一个位置。
在这 5 分钟内,我们
- 使用 `DotNetAge` 项目模板创建了 `DNAMusicStore` 项目。
- 从 ASP.NET MVC MusicStore 复制并合并了必要的文件。
- 设置了 Music Store 网站的基本信息、主题和样式。
- 创建了 `GenrMenuWidget` 和 `TopSellingAlbumsWidget`。
- 添加了小部件并更新了 Music Store 的主页。
扩展 Action
现在你可能会有一个问题:“如何在菜单中添加‘Store’、‘Cart’、‘Admin’页面?”这些链接在 ASP.NET MVC MusicStore 项目的 `Site.Master` 中是硬编码的,我们还需要修改 `Site.Master` 吗?
DotNetAge 的主菜单是动态的,它会自动检测哪些页面可以显示在上面,以及哪些用户可以看到菜单项。DotNetAge 允许开发人员通过“`SiteMapActionAttribute`”指定要在主菜单、`SiteMapPath` 中显示的 Action。
我们将 `SiteMapActionAttribute` 添加到 `ShoppingCartController.Index` Action 和 `StoreController.Index` Action,看看会发生什么。

按“F5”运行项目,并在浏览器中输入 URL“http://[your host name]/store”、“http://[your host name]/shoppingcart”,您将看到 DotNetAge 为您创建了链接到其 Action 的“store”和“cart”菜单。
启用页面上的小部件
我们扩展了可以在主菜单中显示的页面,但它们仍然不支持小部件。有时我们希望我们的 `static` 页面能够通过小部件在运行时进行自定义。转到 `StoreController.Browse` Action 并像这样指定 `SiteMapActionAttibute`:
默认情况下,DotNetAge 会为来自不同 URI 的 Action 自动创建网页,所以我只希望 DotNetAge 为“Browser” Action 创建一个页面,我们将“`IsShared`”属性设置为 `true` 并忽略 Action URI 中的查询字符串字段。
转到 Browse 视图并在此处添加此代码。
我们只需要定义包含小部件的位置,并添加 `class=”ui-widget-zone”`,这些元素将成为小部件容器。
在 View 文件中添加“`Ajax.EnabledCustomization()`”服务器端代码,以告知 DotNetAge 此页面可以包含小部件。
完成后,按 F5 并转到“https://:???/Browse?genre=Rock”,然后单击“SiteTools->Design this page”。

扩展安全性
MVC 提供了一种简单的方法来限制用户或角色访问 Action,但这种方法有一个缺点,即您必须硬编码角色名称或用户名!这不是 MVC 的最佳实践。开发人员不应该知道运行时将使用哪个角色名或用户名,这应该由管理员设置。
DotNetAge 提供了两种在运行时控制安全性的方法,而不是硬编码:
页面可访问角色
DotNetAge WebPage 有一个可访问性设置,我们可以使用此功能来限制用户访问页面。
例如,我们首先使用 `SiteMapActionAttribute` 扩展 `StoreManagerController.Index` Action,然后输入 https://:???/storemanager 并单击“SiteTools->Edit page”。
只需选择可以访问管理页面的角色。

当可访问角色设置页面仅对指定角色可用时,其他角色的用户将无法看到菜单,即使在浏览器中键入 URL,DotNetAge 也会返回“404 Page not found.”。
基于 Action 的架构
另一种在运行时控制 Action 角色或用户访问权限的方法称为“ABA”,我们可以使用 ABA 来扩展 `StoreManagerController`,以展示如何控制 Action 权限。
我们只需在 Action 上使用 `SecurityActionAttribute` 并指定权限标题、描述和组名。按“F5”运行并选择“SiteTools-> Console ”,然后选择“Security”选项卡。
DotNetAge 会自动创建您指定的“`MusicStore`”的 `PermissionSet`。然后您可以将 Action 权限分配给一个或多个角色。

管理员可以根据需要将权限分配给任何角色。
好了!我们只用了 30 分钟就将 ASP.NET MVC Music Store 更新到 DotNetAge,使其功能更强大,可用性更高。尽情享受吧!
资源链接
- ASP.NET MVC MUSIC STORE: http://mvcmusicstore.codeplex.com/
- DotNetAge: http://www.dotnetage.com