Asp.net mvc 3 将HtmlAttributes添加到模板
如果我将HtmlAttributes传递到模板中,如下所示:Asp.net mvc 3 将HtmlAttributes添加到模板,asp.net-mvc-3,razor,html-helper,asp.net-mvc-templates,Asp.net Mvc 3,Razor,Html Helper,Asp.net Mvc Templates,如果我将HtmlAttributes传递到模板中,如下所示: @Html.DisplayFor(m => m.FirstName, new { htmlAttributes = new { @class = "orangetxt strongtxt" } }) DisplayFor(model => model.MyProperty, "MyPropertyTemplate"); 在我的模板中,我将如何将这些内容注入到我的HTML中: <span @ViewData["ht
@Html.DisplayFor(m => m.FirstName, new { htmlAttributes = new { @class = "orangetxt strongtxt" } })
DisplayFor(model => model.MyProperty, "MyPropertyTemplate");
在我的模板中,我将如何将这些内容注入到我的HTML中:
<span @ViewData["htmlAttributes"]>@Model</span>
@模型
这几乎是可行的,但它做了一些非常奇怪的事情,所以我认为这不是解决问题的方法
我意识到我可以通过一个HtmlHelper扩展方法来实现这一点,以呈现完整的HTML元素(本例中为span)并以这种方式传入属性,但是有没有一种方法可以直接将属性呈现到HTML元素中,如上面的示例?DisplayFor()
用于呈现与属性类型匹配的模板
显示模板是/DisplayTemplates文件夹中的.cshtml文件,而该文件夹又位于视图文件夹(即来自主文件夹、共享文件夹甚至特定控制器的任何文件夹)中
举个例子
如果您在/Views/Shared中有类似以下的String.cshtml模板:
它根据字符串的值呈现模板。您可以更具体地将/DisplayTemplates放在特定的视图文件夹中,只有来自这些视图的调用才受模板的影响
在您的情况下,您可以更具体地使用特定模板调用
DisplayFor()
假设您有一个特定属性的模板,名为MyPropertyTemplate.cshtml。您可以这样调用DisplayFor()
:
@Html.DisplayFor(m => m.FirstName, new { htmlAttributes = new { @class = "orangetxt strongtxt" } })
DisplayFor(model => model.MyProperty, "MyPropertyTemplate");
在这个模板中,你可以拥有任何你想要的HTML属性
@model MyProperty
<span class="orangetxt strongtxt">@MyProperty.ToString()</span>
@model-MyProperty
@MyProperty.ToString()
PS:当它找不到模板时,我猜它只调用
model.Property.ToString()
,而不调用其他html
仅供参考:EditorFor()
,例如,其工作方式与之类似,但它使用/EditorTemplates文件夹。试试这个
@Html.DisplayFor(m => m.FirstName,
new { htmlAttributes = "class = orangetxt strongtxt"})
这将呈现一个字符串,而您的版本做了一些奇怪的事情,作为输出的一部分呈现。下面的扩展方法将允许我将HtmlAttributes转换为字符串:
public static MvcHtmlString RenderHtmlAttributes<TModel>(
this HtmlHelper<TModel> htmlHelper, object htmlAttributes)
{
var attrbituesDictionary = new RouteValueDictionary(htmlAttributes);
return MvcHtmlString.Create(String.Join(" ",
attrbituesDictionary.Select(
item => String.Format("{0}=\"{1}\"", item.Key,
htmlHelper.Encode(item.Value)))));
}
publicstaticmvchtmlstring呈现平台属性(
此HtmlHelper HtmlHelper,对象htmlAttributes)
{
var attrbituesDictionary=新的RouteValueDictionary(htmlAttributes);
返回MvcHtmlString.Create(String.Join(“”),
属性描述。选择(
item=>String.Format(“{0}=\”{1}\”,item.Key,
htmlHelper.Encode(item.Value(()())));
}
然后,要在标记中渲染它们,我可以执行以下操作:
<span @Html.RenderHtmlAttributes(ViewData["htmlAttributes"])>@Model</span>
@模型
杰拉德·罗斯的答案很好,但我遇到了几个问题:
- 它不会将属性名称中的下划线转换为破折号
- 它不能优雅地处理无值属性
HtmlHelper.AnonymousObjectToHtmlatAttributes
以下是我对Jerad方法的修改:
public static MvcHtmlString RenderHtmlAttributes(this HtmlHelper helper, object htmlAttributes)
{
if (htmlAttributes == null) return new MvcHtmlString(String.Empty);
var attrbituesDictionary = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
return new MvcHtmlString(String.Join(" ", attrbituesDictionary.Select(item => string.IsNullOrEmpty((string)item.Value) ? String.Format("{0}", item.Key) : String.Format("{0}=\"{1}\"", item.Key, helper.Encode(item.Value)))));
}
谢谢我了解模板是如何工作的,我只需要弄清楚如何将HtmlAttributes传递给模板,并像上面的例子那样呈现它们,而不需要在新模板中硬编码它们。我希望他们更加灵活。模板的问题是,Jerad,htmlAttributes去哪里了?你可以有一个包含很多div的巨大模板。你想做的是非常定制的,它基本上涉及到编写你自己的HtmlHelper方法来输出定制的htmlAttributes。没错,我理解,对于复杂的模板,很难知道
htmlAttributes
将应用于什么。在我的例子中,它将始终应用于模型值周围的元素。比如说,如果我想包括另一个选项来对标签应用自定义属性,那么我可以添加对labelHtmlAttributes
的支持。我真的不想处理所有的字符串转换和编码。实际上,我提出了一个呈现HTML属性的扩展方法,并将在下面发布。@JeradRose-根据您当前的情况,除了对Displayfor的实际调用外,没有任何更改,因此没有转换和编码是,但上面只是一个示例。我可能会遇到属性需要更复杂一些的情况,并且需要引用。例如,如果我需要包含class=“orangetxt strongtxt”id=“myId”
,那么使用您的解决方案会变得有点疯狂。@JeradRose-很公平,我没有理解关于使用多个属性的部分,我的糟糕…嗯,我在这里可能是错的,但是您的预期用途基于这个问题,在我看来,这似乎不起作用。你能告诉我你是如何使用这个助手的吗