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));
}
}
}
在 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));
}
}
}