我希望 System.Web.Mvc.Html 中提供的包装/拦截 HtmlHelper 扩展方法(TextBox、Hidden 等)能够在 2 个单独的用例中重用相同的部分 View 。 部分示例:
@model BlogEntry
@Html.TextBoxFor(t => t.Title)
@Html.TextAreaFor(t => t.Body)
@* Etc *@
Partial 的调用者将知道上下文(即是否覆盖或离开 MS imp)。
覆盖的原因多种多样。例如:在 JQuery 模板中使用,在上面的示例中,值属性的输出将为“${Title}”,或者添加 Html5 元数据。
最佳答案
我不确定您对添加自己的扩展方法有什么顾虑 - 为什么您必须“创建自己的基本 View 页面并完全接管”。您可以在任何页面中调用自定义助手,就像调用内置助手一样:
@Html.TextBoxFor(x => x.Name)
@Html.MyTextBoxFor(x => x.Name)
此外,您可以向方法添加某种标志参数来控制它是只执行默认功能还是自定义功能。
当您创建自己的扩展方法时,您必须更改方法的签名或名称。
我曾经使用唯一的名称,但最终发现我真的希望能够快速区分我自己的实现和默认的实现,所以我有时会使用:
@Html.Custom().TextBoxFor(…
@Html.Custom().TextAreaFor(…
基本上,您创建一个新的扩展方法,该方法采用 HtmlHelper<T>
并返回 CustomHelpers<T>
.
public static CustomHelpers<TModel> Custom<TModel>(this HtmlHelper<TModel> html)
{
return new CustomHelpers<TModel>(html);
}
CustomHelpers<T>
类定义了您自己的所有实现:
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)
}
所以,你的“覆盖”TextBoxFor
可以从您的部分 View 接收一个标志,以确定它是返回 native 结果还是特定于上下文的内容。
同样,CustomHelpers<T>
类(class)完全是可选的。您将添加一个标志参数或类似于自定义助手签名的参数,这样就不会与现有助手发生冲突。
它带来的好处是可以为您的助手命名空间。你可以:
@Html.TextBoxFor(…
@Html.JQuery().TextBoxFor(…
@Html.Mobile().TextBoxFor(…
关于asp.net - 有没有办法动态包装/拦截 HtmlHelper 扩展方法。认为装饰器模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7507711/