views:

721

answers:

2

I want to override Html.TextBoxFor() with my own helper that has the exact same signature (but a different namespace of course) - is this possible, and if so, how?

The reason for this is that I have 100+ views in an already existing app, and I want to change the behaviour of TextBoxFor so that it outputs a maxLength=n attribute if the property has a [StringLength(n)] annotation.

The code for automatically outputting maxlength=n is in this question: http://stackoverflow.com/questions/2386365/maxlength-attribute-of-a-text-box-from-the-dataannotations-stringlength-in-mvc2. But my question is not a duplicate - I am trying creating a more generic solution: where the DataAnnotaion flows into the html automatically without any need for additional code by the person writing the view.

In the referenced question, you have to change every single Html.TexBoxFor to a Html.CustomTextBoxFor. I need to do it so that the existing TextBoxFor()'s do not need to be changed - hence creating a helper with the same signature: change the behaviour of the helper method, and all existing instances will just work without any changes (100+ views, at least 500 TextBoxFor()s - don't want to manually edit that).

I tried this code: (And I need to repeat it for each overload of TextBoxFor, but once the root problem is solved, that will be trivial)

namespace My.Helpers
{
    public static class CustomTextBoxHelper
    {
        public static MvcHtmlString TextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes, bool includeLengthIfAnnotated)
        {
                // implementation here
        }
    }
}

But I am getting a compiler error in the view on Html.TextBoxFor(): "The call is ambiguous between the following methods or properties" (of course). Is there any way to do this?

Is there an alternative approach that would allow me to change the behaviour of Html.TextBoxFor, so that the views that already use it do not need to be changed?

A: 

You can solve this with a editortemplate and a custom ModelMetadataProvider. (Sorry for not giving more info, though this is quite Googleable and I hope this will put you in the right direction.)

svinto
He would still need to replace all the `TextBoxFor` with `EditorFor`.
Darin Dimitrov
Why not just provide a link?
Dan
A: 

You cannot have two extension methods with the same name and the same signature at the same time. You could put your extension method into a custom namespace and use this namespace instead of the default one (System.Web.Mvc.Html) in your web.config:

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

but if you do this you will loose all the other extension methods and you will need to override them in your custom namespace.

Darin Dimitrov
Do you think that instead of removing System.Web.Mvc.Html I could alias it to something else (ala using Foo=namespace), and then for all the methods that I dont need to override, I can just go:YourCompany.Web.Mvc.Html LabelFor(args) {return Foo.LabelFor(args);}?
JK