Asp.net 是否有一种方法可以动态包装/拦截HtmlHelper扩展方法。想想装饰图案
我希望包装/截取System.Web.Mvc.Html中提供的HtmlHelper扩展方法(TextBox、Hidden等),以便在两个单独的用例中重用相同的局部视图。 不包括部分:Asp.net 是否有一种方法可以动态包装/拦截HtmlHelper扩展方法。想想装饰图案,asp.net,asp.net-mvc,asp.net-mvc-3,razor,html-helper,Asp.net,Asp.net Mvc,Asp.net Mvc 3,Razor,Html Helper,我希望包装/截取System.Web.Mvc.Html中提供的HtmlHelper扩展方法(TextBox、Hidden等),以便在两个单独的用例中重用相同的局部视图。 不包括部分: @model BlogEntry @Html.TextBoxFor(t => t.Title) @Html.TextAreaFor(t => t.Body) @* Etc *@ 分部调用方将知道上下文(即,是覆盖还是离开MS imp) 重写的原因是多方面的。例如:在JQuery模板中使用,上面示例中
@model BlogEntry
@Html.TextBoxFor(t => t.Title)
@Html.TextAreaFor(t => t.Body)
@* Etc *@
分部调用方将知道上下文(即,是覆盖还是离开MS imp)
重写的原因是多方面的。例如:在JQuery模板中使用,上面示例中value属性的输出为“${Title}”,或者添加Html5元数据 无法截获对内置助手扩展方法的调用。但是,您可以编写自己的扩展方法,根据上下文做正确的事情 我不确定您对添加自己的扩展方法有何顾虑——为什么您必须“创建自己的基本视图页面并完全接管”。您可以在任何页面中调用自定义帮助程序,就像调用内置帮助程序一样:
@Html.TextBoxFor(x => x.Name)
@Html.MyTextBoxFor(x => x.Name)
此外,您可以向方法添加某种类型的标志参数,以控制它是只执行默认功能还是执行自定义功能
创建自己的扩展方法时,必须更改方法的签名或名称
我曾经使用唯一的名称,但最终发现我真的希望能够快速区分自己的实现与默认实现,因此我有时使用:
@Html.Custom().TextBoxFor(…
@Html.Custom().TextAreaFor(…
基本上,您创建了一个新的扩展方法,该方法接受HtmlHelper
,并返回CustomHelpers
如果您需要这样做,那么您的设计有问题,有另一种方法可以实现。尝试对客户端和服务器模板重复使用相同的html标记是一种糟糕的设计?不,不是。糟糕的设计是试图拦截对标准html帮助程序的调用。我会让Action方法教给HtmlHelper关于上下文的知识。然后它可以决定渲染什么,您也可以使用相同的视图。为什么不创建自己的帮助器来包装MS帮助器并实现自定义逻辑呢?我非常喜欢将呈现转换为文本html或jQuery模板的想法。Intercept是一个错误的词。我想我遇到的一个问题是,HtmlHelper功能是作为扩展方法实现的,据说这样您就可以实现自己版本的TextBox等,但是如果不创建自己的基本视图页面并完全接管它,就无法轻松地“覆盖”或使用自己的CustomHelper。作为一名黑客,我正在考虑做一些类似的事情:@{Html=ViewBag.Html??Html;}@*其中ViewBag有CustomerHelper*@如果MVC能使使用相同的“EditorTemplates”变得容易,我会更喜欢使用jQuery模板等JS很有诱惑力。它也有助于在命名空间
System.Web.Mvc.Html
Jay中声明自定义帮助程序。我非常喜欢您实现帮助程序方法的方式。关键是重用现有视图,而不必经过并将其更改为自定义。目前,似乎只有通过黑客才能实现,请参阅我对@marcind的评论。顺便说一句,如果你去定制,没有从HtmlHelper继承,那么一切都需要重新实现。您的技术适用于其他场景,但从HtmlHelper或HtmlHelper IMHO继承可能更好。
public static CustomHelpers<TModel> Custom<TModel>(this HtmlHelper<TModel> html)
{
return new CustomHelpers<TModel>(html);
}
public class CustomHelpers<TModel>
{
private readonly HtmlHelper<TModel> _html;
public CustomHelpers(HtmlHelper<TModel> html) { _html = html; }
public MvcHtmlString TextBoxFor<TProperty>(Expression<Func<TModel, TProperty>> expression)
{
// because you have a reference to the "native" HtmlHelper<TModel>, you
// can use it here and extend or modify the result, almost like a decorator;
// you can get the "native" result by calling _html.TextBoxFor(expression)
}
@Html.TextBoxFor(…
@Html.JQuery().TextBoxFor(…
@Html.Mobile().TextBoxFor(…