ASP.NET 5(又名 ASP.NET Core),MVC 核心解决方案
在 ASP.NET Core 中,事情得到了进一步优化,因为我们不需要在扩展方法中对标记进行字符串化。
在~/Extesions/HtmlExtensions.cs
:
using System.Text.RegularExpressions;
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Mvc.Rendering;
namespace YourProjectNamespace.Extensions
{
public static class HtmlExtensions
{
private static readonly HtmlContentBuilder _emptyBuilder = new HtmlContentBuilder();
public static IHtmlContent BuildBreadcrumbNavigation(this IHtmlHelper helper)
{
if (helper.ViewContext.RouteData.Values["controller"].ToString() == "Home" ||
helper.ViewContext.RouteData.Values["controller"].ToString() == "Account")
{
return _emptyBuilder;
}
string controllerName = helper.ViewContext.RouteData.Values["controller"].ToString();
string actionName = helper.ViewContext.RouteData.Values["action"].ToString();
var breadcrumb = new HtmlContentBuilder()
.AppendHtml("<ol class='breadcrumb'><li>")
.AppendHtml(helper.ActionLink("Home", "Index", "Home"))
.AppendHtml("</li><li>")
.AppendHtml(helper.ActionLink(controllerName.Titleize(),
"Index", controllerName))
.AppendHtml("</li>");
if (helper.ViewContext.RouteData.Values["action"].ToString() != "Index")
{
breadcrumb.AppendHtml("<li>")
.AppendHtml(helper.ActionLink(actionName.Titleize(), actionName, controllerName))
.AppendHtml("</li>");
}
return breadcrumb.AppendHtml("</ol>");
}
}
}
~/Extensions/StringExtensions.cs
与下面保持相同(向下滚动以查看 MVC5 版本)。
在 razor 视图中,我们不需要Html.Raw
,因为 Razor 在处理 时会处理转义IHtmlContent
:
....
....
<div class="container body-content">
<!-- #region Breadcrumb -->
@Html.BuildBreadcrumbNavigation()
<!-- #endregion -->
@RenderBody()
<hr />
...
...
ASP.NET 4、MVC 5 解决方案
=== 下面是原始/旧答案 ===
(扩展肖恩·哈迪(Sean Haddy)上面的回答)
如果您想让它由扩展驱动(保持视图干净),您可以执行以下操作:
在~/Extesions/HtmlExtensions.cs
:
(兼容MVC5/bootstrap)
using System.Text;
using System.Web.Mvc;
using System.Web.Mvc.Html;
namespace YourProjectNamespace.Extensions
{
public static class HtmlExtensions
{
public static string BuildBreadcrumbNavigation(this HtmlHelper helper)
{
// optional condition: I didn't wanted it to show on home and account controller
if (helper.ViewContext.RouteData.Values["controller"].ToString() == "Home" ||
helper.ViewContext.RouteData.Values["controller"].ToString() == "Account")
{
return string.Empty;
}
StringBuilder breadcrumb = new StringBuilder("<ol class='breadcrumb'><li>").Append(helper.ActionLink("Home", "Index", "Home").ToHtmlString()).Append("</li>");
breadcrumb.Append("<li>");
breadcrumb.Append(helper.ActionLink(helper.ViewContext.RouteData.Values["controller"].ToString().Titleize(),
"Index",
helper.ViewContext.RouteData.Values["controller"].ToString()));
breadcrumb.Append("</li>");
if (helper.ViewContext.RouteData.Values["action"].ToString() != "Index")
{
breadcrumb.Append("<li>");
breadcrumb.Append(helper.ActionLink(helper.ViewContext.RouteData.Values["action"].ToString().Titleize(),
helper.ViewContext.RouteData.Values["action"].ToString(),
helper.ViewContext.RouteData.Values["controller"].ToString()));
breadcrumb.Append("</li>");
}
return breadcrumb.Append("</ol>").ToString();
}
}
}
在~/Extensions/StringExtensions.cs
:
using System.Globalization;
using System.Text.RegularExpressions;
namespace YourProjectNamespace.Extensions
{
public static class StringExtensions
{
public static string Titleize(this string text)
{
return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(text).ToSentenceCase();
}
public static string ToSentenceCase(this string str)
{
return Regex.Replace(str, "[a-z][A-Z]", m => m.Value[0] + " " + char.ToLower(m.Value[1]));
}
}
}
然后像这样使用它(例如在 _Layout.cshtml 中):
....
....
<div class="container body-content">
<!-- #region Breadcrumb -->
@Html.Raw(Html.BuildBreadcrumbNavigation())
<!-- #endregion -->
@RenderBody()
<hr />
...
...