views:

33

answers:

2

I'm building an ASP.NET MVC 2 website and right now, I have ugly spaghetti code in my view which I would like to make into a custom HtmlHelper. The current code in the view is :

            <%switch (Model.fiFieldTypeID) %>
            <%
            {
                case 1: // Text area
                    Response.Write(Html.Encode(Html.TextAreaFor(model => model.fiStrValue)));
                    Response.Write(Html.Encode(Html.ValidationMessageFor(model => model.fiStrValue)));
                    break;
                case 2: // Text box
                    Response.Write( Html.Encode(Html.TextBoxFor(model => model.fiStrValue)));
                    Response.Write( Html.Encode(Html.ValidationMessageFor(model => model.fiStrValue)));
                    break;
etc....

I was trying to encapsulate this code into a neat little HtmlHelper. This is how I started:

public class FormHelpers
{
    public static MvcHtmlString GetStreamFieldEditor(this HtmlHelper html, FieldInstance field)
    {
        string output = "";
        switch (field.fiFieldTypeID)
        {
            case 1: // Text area
                output += html.TextAreaFor(field=> field.fiStrValue).ToString();
etc....

I know my lamda is wrong... but my bigger concern is that TextAreaFor is not available as a method. However, plain old TextArea is available. I don't want to use TextArea because I need to preserve my model binding. How can I use TextAreaFor, TextBoxFor, etc, in my custom html helper?

A: 

Add using System.Web.Mvc.Html.
EDIT: Make sure you're referencing System.Web.Mvc.dll v2.0 or higher.

To fix the lambda, you need to manually generate an expression tree using System.Linq.Expressions.

SLaks
I'm using System.Web.Mvc,Html already. TextAreaFor is still not available.
quakkels
@quakkels: Check the DLL version.
SLaks
I am using mvc 2
quakkels
+3  A: 

How about this:

public static class FormHelpers
{
    public static MvcHtmlString GetStreamFieldEditor(
        this HtmlHelper<YourModelType> html)
    {
        var model = html.ViewData.Model;
        if (model.fiFieldTypeID == 1)
        {
            return html.TextAreaFor(x => x.fiStrValue);
        }
        return html.TextBoxFor(x => x.fiStrValue);
    }
}

And then:

<%: Html.GetStreamFieldEditor() %>
<%: Html.ValidationMessageFor(x => x.fiStrValue) %>
Darin Dimitrov
Interesting, this looks waaaay better than what I was doing. I completely forgot about including the model type in the HtmlHelper parameter: `this HtmlHelper<FieldInstance> html`
quakkels
This is exactly what I needed. Thanks
quakkels