5

We're trying to be type-safe in our views and use the new ExpressionInputExtenssion HtmlHelpers, but we are seeing some inconsistent results. We have a view that looks like this:

ViewData.Model.FooID = <%= ViewData.Model.FooID %><
Model.FooID = <%= Model.FooID  %>       
<%= Html.HiddenFor(x=>x.FooID) %>  

But what we see in the rendered view is this:

ViewData.Model.FooID = 515b0403-e75b-4bd7-9b60-ef432f39d338
Model.FooID = 515b0403-e75b-4bd7-9b60-ef432f39d338    
<input id="FooID" name="FooID" type="hidden" value="" />  

I can manually add this:

<input id="FooID" name="FooID" type="hidden" value="<%= Model.FooID %>" />

But now we are no longer, but surprisingly when I do, The Html.HiddenFor always has the correct value.

4 Answers 4

3

Take a look at this: http://blogs.msdn.com/b/simonince/archive/2010/05/05/asp-net-mvc-s-html-helpers-render-the-wrong-value.aspx

Sign up to request clarification or add additional context in comments.

Comments

2

It looks like the model binder that is behind the extension method cannot convert you FoodID datatype to a string. Is your data type a regular GUID?

I known there are overloads for this extension method for working with binary but I'm not sure about GUIDs ....

Have u tried debbuging it?

3 Comments

It is actually a Nullable<Guid>? No I haven't debugged the HtmlHelper extension just yet. The model binder would wire up the model before the controller action though correct? I can step through my controller action, see me model with the correct value, and even in the view I can see the model with the correct value. I can even see the model value evaluate in the view if I access the property directly.
I just tried this and works fine: <%= Html.Hidden("CustomerGuid", item.CustomerGuid) %> At least this way you can still be type-safe ...
Yea. I could do that, but I was trying to avoid the "CustomerGuid" control name. It would be nice if they would just give you an extension method like Html.IdFor(x=>x.CustomerGuid) and then I could throw it wherever I need. I don't mind writing the HTML, just naming the control. Thanks!
1

I encountered similiar problem, I have one element of the model is hiddeninput, I can see the correct value of this element while displaying view(as debug I show it to check there's correct value in the view), but once I post the view, the return value of this element keeps the first time it's been set, whatever I refresh the display and be sure the correct value shown on the view, but the return value just keep the value been set at first time. This is odd.

Comments

1

You can also roll your own extension that use the value from the property

@Html.HiddenForField(m => m.Location.CityRequired)

public static class HiddenExtensions
{
    public static MvcHtmlString HiddenForField<TModel, TValue>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TValue>> expression) where TModel : class
    {
        var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
        var value = metadata.Model;
        return htmlHelper.HiddenForField(expression, value);
    }

    public static MvcHtmlString HiddenForField<TModel, TValue>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TValue>> expression, object value) where TModel : class
    {
        string htmlFieldName = ExpressionHelper.GetExpressionText(expression);
        string fullName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(htmlFieldName);
        var tag = new TagBuilder("input");
        tag.GenerateId(fullName);
        tag.Attributes.Add("type", "hidden");
        tag.Attributes.Add("name", fullName);
        tag.Attributes.Add("value", value != null ? value.ToString() : string.Empty);
        return new MvcHtmlString(tag.ToString());
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.