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

在 EverLeap 上使用 ASP.NET 5 介绍 TagHelpers

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2015年4月29日

CPOL

8分钟阅读

viewsIcon

32007

在本文中,我们将介绍 TagHelper,了解其优缺点,探索一些 TagHelper 示例,并回顾部署到云托管提供商的体验。

在 ASP.NET 5 中,ASP.NET MVC 开发人员可以使用一种新型预编译用户界面组件,即 TagHelper。使用复杂的交互和功能来构建大型 HTML 和 JavaScript 用户界面非常困难。在本文中,我们将介绍 TagHelper,了解其优缺点,探索一些 TagHelper 示例,并回顾部署到云托管提供商的体验。

什么是 TagHelper

TagHelper 构造通过提供与 MVC 视图中位置上下文相关的标记生成来满足接口抽象需求。我们可以在视图中使用这些 TagHelper,就像引用任何 HTML 标记一样,但我们可以使用我们自己设计的标记和属性。可以通过以下语法在视图中引用一个新的、独特的 TagHelper:

<thumbnail src="/images/Banner-01-Everleap.png" 
    caption="Learn More about Everleap!" 
    alt="EverLeap">
</thumbnail>

这是完全独特、非标准的 HTML,ASP.NET 将理解并调用 TagHelper 来处理缩略图标记,并处理其内容以发送给请求此视图的用户。您还可以将 TagHelper 功能附加到标准 HTML 标记,并指定当这些属性存在时会触发 TagHelper 处理内容的属性。考虑标准的 anchor 元素的标记:

<a asp-action="Index" asp-controller="Home">Home Page</a>

在这种情况下,`asp-*` 属性的存在通过 AnchorTagHelper 源代码中的 if 语句触发了 TagHelper 中的操作代码。AnchorTagHelper 处理此标记后返回的 HTML 如下所示:

<a href="/">Home</a>

编写新的 TagHelper

TagHelper 在 `Microsoft.AspNet.Razor.Runtime` 程序包中由 `Microsoft.AspNet.Razor.Runtime.TagHelpers.TagHelper` 类抽象定义。TagHelper 可以在标准的 .NET 4.6 框架和 .NET Core 框架上运行,因此它们是真正跨平台的。

要定义新的 TagHelper,您可以在 ASP.NET 5 项目或新的 ASP.NET 5 类库项目中创建一个类,并继承自 `TagHelper` 类。有两个方法可以实现:`Process` 和 `ProcessAsync`。在这两个方法中,ASP.NET 会将控制权传递给您,以便您可以修改标签的格式、其属性以及标签中包含的所有内容。

public class MyTagHelper : TagHelper
{

  public override void Process(TagHelperContext context, TagHelperOutput output)
  {
    base.Process(context, output);
  }

  public override Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
  {
    return base.ProcessAsync(context, output);
  }

}

我建议实现 `Process` 方法,并省略 `ProcessAsync` 方法,除非您的代码中需要执行某些异步处理。

ASP.NET 团队当前的编码标准要求我们将 TagHelper 类命名为以 TagHelper 为后缀。按照惯例,TagHelper 前面的名称是激活此 TagHelper 的 HTML 元素的名称。在上面的示例代码中,`` 标记将激活 Process 方法。

您可以通过用一个指定了触发您的代码的元素名称的 `TargetElement` 属性来装饰您的 TagHelper 类来覆盖此约定:

[TargetElement("m")]
public class MyTagHelper : TagHelper
{

让我们看一些创建 TagHelper 的实际示例,以帮助实现 bootstrap 组件更加容易。

Bootstrap Headers (Bootstrap 头部)

为了实现 bootstrap 响应式 Web 框架,其网站指示我们从其 CDN 引用两个样式表和一个脚本文件。我们可以通过实现一个 `HeadTagHelper` 来自动化此操作,它会为我们插入这些元素。 `HeadTagHelper` 类的初始代码如下所示:

  public class HeadTagHelper : TagHelper
  {
    public override void Process(TagHelperContext context, TagHelperOutput output)
    {

      base.Process(context, output);

    }

  }

请注意,我没有为此类包含 `TargetElement` 属性,因为我想让它触发标准的 HTML head 元素。接下来,我想确保我的 head 元素内容中当前没有定义任何 bootstrap 引用。这将防止重复引用 bootstrap 库。

    public override void Process(TagHelperContext context, TagHelperOutput output)
    {

      base.Process(context, output);

      if (!output.Content.GetContent().Contains("bootstrap"))
      {

我们可以检查 `TagHelperOutput` 对象,以查看 head 标签中已有的内容。默认情况下,TagHelper 不会修改其正在操作的标签的内容或属性。此时在 `Process` 方法中,head 元素没有任何变化。通过调用 `GetContent()` 方法,我们将原始 razor 标记中的所有内部内容作为连续字符串检索以进行检查。

在确保 head 元素中没有引用 bootstrap 后,我就可以添加我的 CSS 和 JavaScript 引用了。

      if (!output.Content.GetContent().Contains("bootstrap"))
      {
        var cdn = "https://maxcdn.bootstrap.ac.cn/bootstrap/3.3.4/";
        output.PostContent.Append(@"<link rel=""stylesheet"" href=""" + cdn + @"css/bootstrap.min.css"">");
        output.PostContent.Append(@"<link rel=""stylesheet"" href=""" + cdn + @"css/bootstrap-theme.min.css"">");
        output.PostContent.Append(@"<script src=""" + cdn + @"js/bootstrap.min.js""></script>");
      }

太好了。现在我可以在我的布局页面中的 TagHelper 中添加一个指令,并强制确保这些引用始终存在。

@addTagHelper "HeadTagHelper, TagHelperSample.Helpers"
<!DOCTYPE html>

`addTagHelper` 指令接受一个完全限定的类名,以指示 razor 解释器在处理 razor 标记时包含这些类。您可以选择使用通配符 (*) 来指示逗号后面的程序集名称中的所有类都将被引用。最后,addTagHelper 指令仅适用于已添加该指令的 razor 页面,并且不会级联到可能被引用或包含的其他页面。

更复杂的示例 – Thumbnails (缩略图)

在此示例中,我们将回顾为 bootstrap thumbnail 组件创建 TagHelper。在此示例中,我们不涉及传递全尺寸图像,而是仅传递一个缩略图组件,该组件显示全尺寸图像的浏览器缩放版本。将要传递给浏览器的预期输出如下所示:

  <div class="thumbnail">
    <img src="IMAGE SOURCE" alt="ALT TEXT" />
    <div class="caption">
      <h3>CAPTION TEXT</h3>
    </div>
  </div>

我们可以将这三个自定义输入定义为自定义缩略图元素的属性,该元素在 razor 中看起来会像这样:

<thumbnail src="IMAGE SOURCE" caption="CAPTION" alt="ALT TEXT"></thumbnail>

我们已经知道如何开始一个 TagHelper 类,但这次我们将需要 `src` 属性才能继续。

  [TargetElement("thumbnail", Attributes = "src")]
  public class ThumbnailTagHelper : TagHelper
  {

    public override void Process(TagHelperContext context, TagHelperOutput output)
    {

`TargetElement` 属性上的 `Attributes` 参数是一个逗号分隔的属性名称列表,在 razor 页面上使用此 TagHelper 类之前必须出现这些属性。在这种情况下,如果缺少 `src` 属性,则会将缩略图标记作为 HTML 发送给请求的客户端。让我们开始转换此标签的输出,以生成具有缩略图类的外部 div 标签,并删除缩略图元素:

    public override void Process(TagHelperContext context, TagHelperOutput output)
    {

      output.TagName = "div";
      output.Attributes["class"] = "thumbnail";

通过将 `TagName` 属性设置为 "div",razor 将用 div 标签替换原始缩略图标签,并保留附加到该元素的所有原始属性。第二个命令将 div 的 class 属性设置为 "thumbnail",这是 bootstrap 对此组件的要求。

  var sb = new StringBuilder();
  sb.AppendFormat("<img src=\"{0}\"", context.AllAttributes["src"].ToString());
  if (context.AllAttributes.ContainsKey("alt"))
  {
    sb.AppendFormat(" alt=\"{0}\"", context.AllAttributes["alt"]);
  }
  sb.Append("/>");

接下来,我使用 StringBuilder 来收集正在构造和输出的元素。首先,定义图像标签,如果原始缩略图元素属性中指定了 alt 文本,则该文本将作为 alt 属性输出到图像标签中。

  if (context.AllAttributes.ContainsKey("caption"))
  {
    sb.AppendFormat("<div class=\"caption\"><h3>{0}</h3></div>", context.AllAttributes["caption"]);
  }

如果缩略图元素上指定了 caption 属性,则根据 bootstrap 文档的规定,我们将使用规定的标记来输出它。接下来,我想删除缩略图元素上的额外属性,这些属性是我们不希望在新 div 元素上发出的:

  foreach (var item in new[] { "src","alt","caption" })
  {
    output.Attributes.Remove(item);
  }

然后,我们可以清除原始缩略图元素的内容,并用 StringBuilder 中存储的标记替换它。

      output.Content.SetContent(sb.ToString());

      base.Process(context, output);
    }

关于使用 TagHelpers 的最后一点说明,当我们在代码中开始使用这个缩略图标签时,在 Visual Studio 中默认看起来是这样的:

  <thumbnail  src="http://lorempixel.com/400/400/cats"
              caption="A random cat picture"
              alt="Cats!">
  </thumbnail>

请注意,标签名称会更改为粗体紫色。这表明在将此标签传递给请求的客户端之前,它正在被作为 C# 代码处理。

发布到云

我选择使用 Everleap 这样的优质提供商将我的示例内容发布到云端。Everleap 拥有您期望的所有丰富的云弹性资源,并且已经支持运行 ASP.NET 5 Web 应用程序。将此应用程序部署到 Everleap 云有多么容易,如下所示。

我首先从我的控制台 cp.everleap.com 下载了我的 Everleap 发布配置文件。

我通过右键单击解决方案资源管理器中的项目名称并选择 "Publish" 来进入我的项目的发布对话框。

我点击 "Import" 并选择了从 Everleap 控制面板下载的配置文件。导入配置文件后,点击左侧列表中的配置文件选项,然后将配置文件更改为 FTP 发布。

在下一个屏幕上,将站点路径更改为 "site" 文件夹并输入您的密码。

接下来,使用适当的 DNX 框架版本配置发布设置,取消选中 "delete all existing files" 选项,并取消选中 "Publish with Powershell" 选项。

就这样……点击发布,您的应用程序就会加载到您的 Everleap 服务器上。请记住,在新的 ASP.NET 5 模型中,DNX 框架是可移植且模块化的。您最初将加载应用程序运行所需的所有 DNX 框架部分。在后续的发布中,只有您的更改文件将被加载到服务器。

摘要

ASP.NET 5 是对 ASP.NET 运行时及其框架协同工作方式的全面重新思考。MVC 开发人员的编程模型没有发生显著变化,但通过引入 TagHelpers,我们构建视图的任务变得更加简单,可以使用可重用的代码,这些代码可以放置在共享库和 NuGet 包中供您的整个组织使用。得益于 Everleap 规划并尽早采用这些新标准,将您的新应用程序加载到 Everleap 等云提供商上非常容易。

您可以在 http://1786-4973.el-alt.com/ 查看 TagHelpers 演示站点。

有关 ASP.NET 应用程序云托管的更多信息,请访问 Everleap.com

© . All rights reserved.