ASPNET MVC – 使用具有相同签名的新助手覆盖Html.TextBoxFor(model.property)?
我想用我自己的帮助器覆盖Html.TextBoxFor(),该帮助器具有完全相同的签名(当然是一个不同的命名空间) – 这是可能的,如果是这样,怎么样?
这样做的原因是我在现有应用程序中有100多个视图,我想改变TextBoxFor的行为,以便在属性具有[StringLength(n)]注释时输出maxLength = n属性。
自动输出maxlength = n的代码在这个问题中: 来自Asp.Net MVC中DataAnnotations StringLength的文本框的maxlength属性 。 但我的问题并不重复 – 我正在尝试创建一个更通用的解决方案:DataAnnotaion自动流入html,而不需要编写视图的人员需要额外的代码。
在引用的问题中,您必须将每个Html.TexBoxFor更改为Html.CustomTextBoxFor。 我需要这样做,以便不需要更改现有的TextBoxFor() – 因此创建一个具有相同签名的帮助程序:更改辅助方法的行为,并且所有现有实例都可以正常工作而不做任何更改(100 + views,至少500 TextBoxFor()s – 不想手动编辑它)。
我尝试了这段代码:(我需要为TextBoxFor的每次重载重复它,但一旦根问题解决了,那将是微不足道的)
namespace My.Helpers { public static class CustomTextBoxHelper { public static MvcHtmlString TextBoxFor(this HtmlHelper htmlHelper, Expression<Func> expression, object htmlAttributes, bool includeLengthIfAnnotated) { // implementation here } } }
但是我在Html.TextBoxFor()视图中遇到编译器错误:“调用在以下方法或属性之间是不明确的”(当然)。 有没有办法做到这一点?
是否有一种替代方法可以让我改变Html.TextBoxFor的行为,以便不需要更改已经使用它的视图?
您不能同时拥有两个具有相同名称和相同签名的扩展方法。 您可以将扩展方法放入自定义命名空间,并使用此命名空间而不是web.config中的默认命名空间(System.Web.Mvc.Html):
但是如果你这样做,你将失去所有其他扩展方法,你需要在自定义命名空间中覆盖它们。
简短的回答,不,你不能“替换”现有的扩展方法。
更长的答案,你可能会通过一些非常邪恶的反思来做到这一点……虽然我非常怀疑这甚至会起作用。 这些方面的东西:
// Get the handle for the RuntimeMethodInfo type var corlib = Assembly.GetAssembly(typeof (MethodInfo)); var corlibTypes = corlib.GetModules().SelectMany(mod => mod.FindTypes((a, b) => true, null)); Type rtmiType = corlibTypes.Where(t => t != null && t.FullName != null && t.FullName.Contains("Reflection.RuntimeMethodInfo")).First(); // Find the extension method var methods = typeof (Html).GetMethods(BindingFlags.Static | BindingFlags.Public); foreach (var methodInfo in methods) { if (methodInfo.Name == "TextBoxFor") { // Try to monkeypatch this to be private instead of public var methodAttributes = rtmiType.GetField("m_methodAttributes", BindingFlags.NonPublic | BindingFlags.Instance); if(methodAttributes != null) { var attr = methodAttributes.GetValue(methodInfo); attr = ((MethodAttributes)attr) | MethodAttributes.Private; methodAttributes.SetValue(methodInfo, attr); } } }
您可以使用editortemplate和自定义ModelMetadataProvider来解决此问题。 (很抱歉没有提供更多信息,虽然这非常适合Google,我希望这会让你朝着正确的方向前进。)
- 在自定义AuthorizeAttribute中获取Post请求参数
- Visual Studio 2010中的ASP.Net MVC 1.0
- ASP.NET MVC C#:将来自多个表/查询的数据引入视图
- 如何使用LinqToExcel获取excel文件的工作表名称
- 当前上下文中不存在名称“DefaultAuthenticationTypes”
- Google Chrome的ASP.NET MVC Session.IsNewSession问题
- 在启用了LowercaseUrls的Route参数中保留Case
- 如何确定任意URL是否与定义的路由匹配
- 为什么我的视图模型不能与实现接口的通用ViewModel绑定? (ASP.NET MVC 3)