Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ASPNET MVC-使用具有相同签名的新帮助程序覆盖Html.TextBoxFor(model.property)?_C#_Asp.net Mvc_Data Annotations_Html Helper - Fatal编程技术网

C# ASPNET MVC-使用具有相同签名的新帮助程序覆盖Html.TextBoxFor(model.property)?

C# ASPNET MVC-使用具有相同签名的新帮助程序覆盖Html.TextBoxFor(model.property)?,c#,asp.net-mvc,data-annotations,html-helper,C#,Asp.net Mvc,Data Annotations,Html Helper,我想用我自己的助手覆盖Html.TextBoxFor(),它具有完全相同的签名(当然是不同的名称空间)——这可能吗?如果可能,如何实现 原因是我在一个已经存在的应用程序中有100多个视图,我想更改TextBoxFor的行为,以便在属性具有[StringLength(n)]注释时,它输出maxLength=n属性 自动输出maxlength=n的代码在此问题中:。但我的问题不是重复的——我正在尝试创建一个更通用的解决方案:数据注释自动流入html,而无需编写视图的人编写额外的代码 在参考问题中,您

我想用我自己的助手覆盖Html.TextBoxFor(),它具有完全相同的签名(当然是不同的名称空间)——这可能吗?如果可能,如何实现

原因是我在一个已经存在的应用程序中有100多个视图,我想更改TextBoxFor的行为,以便在属性具有[StringLength(n)]注释时,它输出maxLength=n属性

自动输出maxlength=n的代码在此问题中:。但我的问题不是重复的——我正在尝试创建一个更通用的解决方案:数据注释自动流入html,而无需编写视图的人编写额外的代码

在参考问题中,您必须将每个Html.TexBoxFor更改为Html.CustomTextBoxFor。我需要这样做,以便不需要更改现有的TextBoxFor(),从而创建一个具有相同签名的帮助器:更改帮助器方法的行为,所有现有实例都将在不做任何更改的情况下工作(100多个视图,至少500个TextBoxFor(),不希望手动编辑)

我尝试了这段代码:(我需要为TextBoxFor的每个重载重复它,但一旦根本问题得到解决,这将是微不足道的)

名称空间My.Helpers
{
公共静态类CustomTextBoxHelper
{
public static MvcHtmlString TextBoxFor(此HtmlHelper HtmlHelper、表达式、对象htmlAttributes、bool includeLength未说明)
{
//在这里实现
}
}
}
但是我在Html.TextBoxFor()的视图中遇到一个编译器错误:“调用在以下方法或属性之间是不明确的”(当然)。有没有办法做到这一点


是否有另一种方法允许我更改Html.TextBoxFor的行为,以便已经使用它的视图不需要更改?

您可以使用editortemplate和自定义ModelMetadataProvider解决此问题。(很抱歉没有提供更多信息,尽管这很容易收集,我希望这会让您找到正确的方向。)

您不能同时拥有两个具有相同名称和相同签名的扩展方法。您可以将扩展方法放入自定义名称空间,并使用此名称空间,而不是Web.config中的默认名称空间(System.Web.Mvc.Html):

<pages>
    <namespaces>
        <!--<add namespace="System.Web.Mvc.Html"/>-->
        <add namespace="YourCompany.Web.Mvc.Html"/>
    </namespaces>
</pages>


但是如果这样做,您将丢失所有其他扩展方法,并且需要在自定义命名空间中重写它们。

简短回答,不,您不能“替换”现有的扩展方法

回答得再长一点,你们也许可以通过一些极端邪恶的思考来做到这一点……尽管我高度怀疑这是否可行。大致如下:

        // 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);                
                }
            }
        }

他仍然需要将所有的
TextBoxFor
替换为
EditorFor
。你认为我不需要删除System.Web.Mvc.Html,而是可以将它别名为其他东西(ala使用Foo=namespace),然后对于所有我不需要重写的方法,我只需要:YourCompany.Web.Mvc.Html LabelFor(args){return Foo.LabelFor(args);}?嗨,Darin,我同意在这种特殊情况下覆盖扩展似乎是不可能的。但是我不同意你的说法,“你不能有两个扩展方法同时具有相同的名称和相同的签名。”如果你把扩展方法放在同一个命名空间中(或者层次结构中只有几个命名空间)对于您的消费类,这是非常有可能的。下面的帖子中有一个这样做的例子:Visual Studio的查找和替换功能非常强大。它可以用
Html.TextBoxFor
替换解决方案中出现的所有
Html.CustomTextBoxFor
,只需单击一次!您不需要手动编辑任何文件以重命名方法。
        // 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);                
                }
            }
        }