65.9K
CodeProject 正在变化。 阅读更多。
Home

Slink 框架 - ASP.NET 的强类型 URL

starIconstarIconstarIconstarIconstarIcon

5.00/5 (11投票s)

2007年9月4日

8分钟阅读

viewsIcon

58006

Slink 是一个代码生成框架,它为 ASP.NET 生成类型安全的 URL。使用 Slink URL,您可以提高代码质量,增加可维护性,并在所有 ASPX 页面(代码隐藏和非代码隐藏)中获得 URL 的编译时检查。

Screenshot - namespaceview.gif Screenshot - rootnamespace.gif

引言

我决定是时候解决在使用 ASP.NET 和 Visual Studio 时一个非常恼人且耗时的代码维护/质量问题了,那就是 URL 验证。如果你和我一样,你可能在重命名 Web 项目中的文件时遇到过不少 HTTP 404 错误和 ASP.NET 维护问题,以及代码隐藏页面中散布的 Response.Redirect() 类似以下情况的损坏 URL。

protected void Page_Load(object sender, EventArgs e)
{
    if ( User.IsInRole( "admin" ) )
    {
        Response.Redirect( "~/Page2.aspx" );
    }
    if( User.IsInRole( "employee" ) )
    {
        Response.Redirect( "~/EmployeePages/ViewCustomers.aspx" );
    }
    if( User.IsInRole("customer") )
    {
        Response.Redirect( "~/CustomerPages/ViewCatalog.aspx" );
    }
}

Visual Studio 中的站点验证在验证 URL 的能力上有些受限。Visual Studio 会验证 HTML 标记视图中的 URL,但不会验证代码隐藏页面中的 URL。这很令人沮丧,因为上面的代码在项目中很常见。代码隐藏页面中存在的无效 URL 很难调试和定位……你通常只有在浏览器访问该页面时才会知道代码隐藏中潜伏着无效 URL。如今大多数现代重构工具在重命名文件时都能很好地重构代码;然而,由于大多数重构工具在重命名 ASPX 文件时都在搜索字符串,因此存在出错的可能性。在重构时,很多时候选择“搜索字符串字面量”选项不仅没有帮助,反而使问题变得更糟。当你开始处理标记和代码隐藏页面中的不同媒体类型(如图像、SWF、CSS 和 JavaScript URL)时,可重构性会下降。这些媒体类型未经检查,尝试在你的页面中重构它们吧!就我个人而言,如果能有某种强类型 URL 框架,我会非常高兴。

现有工作,PageMethods

幸运的是,Fabrice Marguerie 及其开源项目 PageMethods 在这方面已经做了一些工作。

在使用 PageMethods 后,我很快发现:

  • 截至本文撰写之时,PageMethods 不会为没有 [PageMethod] 属性的页面生成 URL。
  • PageMethods 不会为 ASPX 页面以外的媒体类型生成 URL。你不能将 PageMethods URL 用于 JavaScript、CSS、SWF 或其他图像。
  • PageMethods 有点慢。对于一个有大约 5 个页面的项目,PageMethods 使我的构建时间增加了大约 5 秒。
  • PageMethods 在 PageLoad 中使用 BasePageInvoke(this)。虽然不是必需的,但它增加了你的页面层次结构。

总而言之,PageMethods 太严格了,不适合我的目的。我只是想要一个轻量级且快速的 URL 框架,用于提供指向页面和媒体对象的链接,我可以在代码隐藏页面和 HTML 标记中使用这些链接。我还想在编译时知道项目中所有 URL 的有效性。所以,我决定自己解决这个问题,我创建了一个名为 (Strong Link),又名 Slink 的小项目。

Slink

现在,让我们使用带有强类型 URL 的 Slink 重新审视上述相同的可维护性问题

protected void Page_Load( object sender, EventArgs e )
{
    if( User.IsInRole( "admin" ) )
    {
        Response.Redirect( Slinks.Page2.TidleUrl );
    }
    if( User.IsInRole( "employee" ) )
    {
        Response.Redirect( Slinks.EmployeePages.ViewCustomers.TildeUrl );
    }
    if( User.IsInRole( "customer" ) )
    {
        Response.Redirect( Slinks.CustomerPages.ViewCatalog.TildeUrl );
    }        
}

有了 Slink,你不仅能获得更简洁的代码,还能获得代码隐藏页面的编译时检查!你还可以在 HTML 标记中使用类型安全的链接

<h4>Customer Pages</h4>
<!-- The old way, using relative path -->
<img src="~/Images/CustomerImage.jpg" alt="not strongly typed image" />

<!-- The new Slink type safe way, using img HTML tag -->
<img src='<%# Slinks.Images.JPG.CustomerImage.TildeUrl %>' alt="strongly typed url" runat="server" />


<!-- The new Slink type safe way, using a web control -->
<asp:Image ID="imgControl" runat="server"
ImageUrl='<%# Slinks.Images.JPG.CustomerImage.TildeUrl %>' />

是的!还有更多优点

  • 更易维护的代码
  • 更简洁的代码
  • 更易读的代码
  • 更易重构的代码
  • 更高质量的代码
  • 支持 ASPX 页面以外的媒体类型
  • 快速代码生成
  • 非侵入式开销(无需调用任何设置方法或昂贵的运行时检查)
  • 即用型集成(无需重写任何代码即可开始使用 Slink
  • 基于 XML 配置
  • 为你的任何文件和媒体对象提供 Intellisense!

这才是我想要的。那么,如何才能获得所有这些 Slink ASP.NET 的好处呢?请继续阅读...

Slink 入门

使用 Slink 有两种基本方法

  • 您可以使用 Visual Studio 和随附的 CR_Slink 插件(通过 DXCore)在项目的 _App_Code_ 目录中自动生成类型安全文件。

或者

  • 您可以在构建任务中使用 _Slink.exe_ 在 _App_Code_ 目录中生成强类型安全文件。

有关如何设置每种方法的详细信息将在稍后讨论。首先,您需要执行一些 XML 配置来告诉 Slink 要生成什么。以下是您放置在 _Web.config_ 中的示例配置

<!-- Web.config -->
<configuration>
    <configSections>
        <section name="Slink" type="Slink.Core.SlinkConfigSection, 
            Slink.Core"/>
    </configSections>
    <Slink>
        <GlobalSettings EngineEnabled="True" RootNamespace="Slinks" 
            TypesafeGeneratedFileTarget="App_Code\Slinks.cs"/>
        <NamespaceRules>
            <add key="aspxFiles" Extension="*.aspx" UseFolderNamespace="True"/>
            <add key="jpgFiles" Extension="*.jpg" 
            NamespaceOverride="Images.JPG"/>
            <add key="pngFiles" Extension="*.png" 
            NamespaceOverride="Images.PNG"/>
        </NamespaceRules>
    </Slink>
<!-- Other configuration settings go here -->
</configuration>

以下是 XML 配置设置的简要说明...

<section name="Slink" type="Slink.Core.SlinkConfigSection, Slink.Core"/>
  • 此节处理程序需要添加到 <configSections> 中。<section> 标签定义了要由 SlinkConfigSection 代表 .NET 配置框架处理的 XML 节点。
<Slink>
<GlobalSettings EngineEnabled="True" RootNamespace="Slinks"/>
  • <GlobalSettings> 节点有两个属性 EngineEnabledRootNamespace
    • EngineEnabled - 布尔值 - 这是一个项目级别设置。如果您正在处理多个 Web 项目,您可能希望在项目级别禁用类型安全链接代码生成。将 EngineEnabled="False" 设置为禁用 Web 项目级别的代码生成。
    • RootNamespace - 字符串 - 允许您指定所有类型安全链接的命名空间。

      Screenshot - rootnamespace.gif

    • TypesafeGeneratedFileTarget - 字符串 - 允许您指定生成类型安全代码的输出文件。
注意:本例中的 _Web.config_ 使用 VS.NET 2005 中的“网站项目”模型。如果您使用的是 Visual Studio 中的“Web 应用程序项目”模型,则必须从 TypesafeGeneratedFileTarget 中移除 App_Code,并将其放置在 App_Code 以外的其他位置。请阅读此处的第 4 步,了解为什么不应将代码放置在“Web 应用程序项目”的 App_Code 中。有关“Web 应用程序项目”和“网站项目”之间差异的更多信息,请单击此处
<NamespaceRules>
    <add key="aspxFiles" Extension="*.aspx" UseFolderNamespace="True"/>
    <add key="jpgFiles" Extension="*.jpg" NamespaceOverride="Images.JPG"/>
    <add key="pngFiles" Extension="*.png" NamespaceOverride="Images.PNG"/>
</NamespaceRules>
  • <NamespaceRules>Slink 的核心。命名空间规则规定了 Slink 引擎如何生成类型安全代码。命名空间规则允许您定义哪种类型的文件获得类型安全。
    • Extension - 字符串 - 如果您希望为所有 ASPX 页面生成类型安全代码,请添加一个命名空间规则,并将 Extension 属性设置为 *.aspx。包含 *(星号)是必要的。
    • UseFolderNamespace - 布尔值 - 使用文件路径在根命名空间下生成子命名空间。
    • NamespaceOverride - 字符串 - 覆盖 UseFolderNamespace 属性,允许您定义自己的自定义路径。您的自定义命名空间覆盖将附加到 RootNamespace。请参阅下面的 JPG 和 PNG 命名空间覆盖示例

Screenshot - namespaceview.gif

注意:如果您有多个具有相同名称但不同扩展名的文件,您需要覆盖命名空间以避免类型冲突。

现在我们已经完成了 XML 配置,我将向您介绍如何在您的机器上安装 Slink

使用 Visual Studio Slink 插件

Screenshot - slinkplugin2.gif

安装 VS.NET 插件

  1. 从 Developer Express 此处安装 DXCore (免费) Visual Studio 可扩展性框架。
  2. 下载 Slink 二进制文件 Slink_bin.zip
  3. 将 _Slink_bin.zip_ 的内容复制到您的 DXCore 插件目录中
    • 例如: _C:\Program Files\Developer Express Inc\DXCore for Visual Studio .NET\2.0\Bin\Plugins_
    • 注意:_Slink_bin.zip_ 的所有内容都必须解压到 _plugins_ 目录中
  4. 通过运行 _InstallSlink.bat_ 注册二进制包中附带的 Code Smith 解析器 COM 组件。
  5. 确保您的 XML 配置部分已在 _Web.config_ 中定义,然后开始编码!

使用 Slink.exe

Screenshot - slinkplugin.gif

现在,如果您已经在使用 Visual Studio 插件,则无需使用 _Slink.exe_。但对于那些没有 Visual Studio,或正在使用 Visual Studio Express 的人来说,使用 _Slink.exe_ 是一个不错的选择。

安装 Slink.exe

  1. 下载 Slink 二进制文件 Slink_bin.zip
  2. 将内容解压到您选择的目录中
    • 例如 _C:\Tools\Slink_
  3. 通过运行 _InstallSlink.bat_ 注册二进制包中附带的 Code Smith 解析器 COM 组件。
  4. 从命令行运行以下命令
    • C:\Tools> slink.exe /webproject:<WebProject路径>
    • <PathToWebProject> 替换为您的项目的完整路径
  5. 请务必修改您的 _Web.config_ 并设置好您的命名空间规则。否则,Slink 将不知道该做什么。

提示:遗憾的是,Visual Studio 中的“网站项目”模型与普通项目处理方式不同。对于“网站项目”,您无法指定任何“预构建”事件任务。但有一个简单的变通方法可以解决此限制。如果您正在使用 Visual Studio“网站项目”模型,并且想使用 _Slink.exe_ 方法生成类型安全文件,您只需创建一个标准的虚拟“类库”。然后为您的虚拟“类库”添加一个预构建任务,并设置 Slink 执行。一旦您将虚拟“类库”添加到您的主 Web 项目,您的虚拟“类库”将首先构建(并且 Slink 将运行),然后才在您的主 Web 项目上进行构建/验证过程。

就是这样!构建 Web 项目后(如果您使用的是 VS.NET Slink 插件),或者执行 _Slink.exe_ 时,您应该会得到一个名为 _<WebProject>\App_Code\Slinks.cs_ 的文件,其中包含您生成的类型安全 URL 代码。

如果您有任何问题、意见或建议,请随时与我联系。我希望其他开发人员能发现 Slink 框架有用。祝您编程愉快!

另外,最后一点说明,请使用 CodePlex 上的最新二进制文件!Code Project 上的二进制文件可能已过时。

Slink CodePlex 项目

查看 Brian Chavez 关于 Slink帖子

Slink 的想法和未来改进

  • 增加对查询字符串参数的强类型参数传递/解析支持
  • 创建一个不依赖于 DXCore 的独立 Slink 插件
  • 实现更高级的代码生成缓存
  • 可能会在媒体类型(如 MyImage.GetStream())上实现/生成一个辅助方法,该方法将自动打开并返回一个 IO 流。

Licence

此库和代码生成器根据 GNU 公共许可证中定义的条款和条件获得许可。您可以免费将其用于非商业目的。如果您打算在商业应用程序中使用其任何部分,请与我联系,我们可以协商。您可以在商业和非商业应用程序中使用 Slink 生成的代码输出。

特别感谢

特别感谢 Philip Laureano 构建了他的开源 TaHoGen 代码模板生成器。没有它,Slink 将不复存在。

历史

  • 版本 0.7.0.2 发布 - 修复了 COM 初始化错误,在插件中增加了对 Web 应用程序项目的支持
  • 版本 0.7.0.1 发布 - 代码生成器中的错误修复,清理了文章格式
  • 版本 0.7.0.0 发布 - 初稿,第一版文章
© . All rights reserved.