ASP 个具有 HTML 内容的 MVC ActionLink

ASP MVC ActionLinks with HTML content

在 ASP MVC 中有很好的扩展方法可以生成 ActionLinks/RouteLinks。但是,它只允许您在生成的标签内写入纯文本。如果想生成内含图片的anchor怎么办?

我想使用 bootstrap 中的图标创建 links:

// expected result
<a href="/Customer?page=1"><i class="glyphicon glyphicon-arrow-left"></i> Previous page</a>

当你想生成简单的link时,你可以像这样使用@Url.Action():

<a href="@Url.Action("Index","Customer", new{ page = 1 })"><i class="glyphicon glyphicon-arrow-left"></i> Previous page</a>

但是当你想生成ajax link时,就没那么简单了。因为@Ajax.ActionLink 生成具有 javascript 或 'data-*' 属性的锚点,这些属性由 jquery-unobtrusive-ajax-min.js 库处理。

所以我为了我的目的写了扩展方法来生成 ActionLinks/RouteLinks 在你使用 @Html.BeginForm/@Ajax.BeginForm 的方式(被 using 包围)。

用法:

// instead
@Html.ActionLink("Previous page", "Index", "Customer", new { page = 1 })

// you can write
@using(Html.BeginActionLink("Index", "Customer", new { page = 1 }) {
  <text><i class="glyphicon glyphicon-arrow-left"></i> Previous page</text>
}

// same with ajax links
@using(Ajax.BeginActionLink("Index", new { page = 1 }, new AjaxOptions { ... }) {
  <text><i class="glyphicon glyphicon-arrow-left"></i> Previous page</text>
}

方法 BeginActionLink return class MvcLink 的实例,它实现了 IDisposable。在构造函数中,它写入开始标记,并在处理时写入结束标记。在花括号之间有你的代码的位置

namespace System.Web.Mvc
{
  using System.Text.RegularExpressions;

  public class MvcLink : IDisposable
  {
    internal static readonly string InnerText = "___F7ED35E0097945398D5A969F8DE2C63C___";
    private static readonly Regex RegexPattern = new Regex(@"^\s*(?<startTag>.*)\s*" + InnerText + @"\s*(?<endTag>.*)\s*$", RegexOptions.Compiled | RegexOptions.Singleline);

    private readonly ViewContext _viewContext;
    private readonly string _endTag;

    internal MvcLink(ViewContext viewContext, IHtmlString actionLink) {
      _viewContext = viewContext;
      var match = RegexPattern.Match(actionLink.ToHtmlString());
      if (match.Success) {
        var startTag = match.Groups["startTag"].Value;
        _endTag = match.Groups["endTag"].Value;
        _viewContext.Writer.Write(startTag);
      }
    }

    public void Dispose() {
      _viewContext.Writer.Write(_endTag);
    }
  }
}

那么就看你写HtmlHelper和AjaxHelper的扩展方法了。方法 ActionLink/RouteLink 的重载太多,所以我只准备了我在应用程序中真正使用的重载。

但是写其他的很容易。您可以看到我创建了 MvcLink 的实例,它以 ViewContext 作为第一个参数以及带有预定义 InnerText 的内置 ActionLink 的结果将被您的内容替换。

namespace System.Web.Mvc
{
  using System.Web.Mvc.Ajax;
  using System.Web.Mvc.Html;

  public static class MvcHelperExtensions
  {
    public static MvcLink BeginActionLink(this AjaxHelper ajaxHelper, string actionName, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes) {
      return new MvcLink(ajaxHelper.ViewContext, ajaxHelper.ActionLink(MvcLink.InnerText, actionName, routeValues, ajaxOptions, htmlAttributes));
    }

    public static MvcLink BeginActionLink(this HtmlHelper htmlHelper, string actionName, object routeValues, object htmlAttributes) {
      return new MvcLink(htmlHelper.ViewContext, htmlHelper.ActionLink(MvcLink.InnerText, actionName, routeValues, htmlAttributes));
    }
  }
}