locked
ASP.NET MVC3 RC2 bug binding from request parameters to method parameters RRS feed

  • Question

  • User1205957345 posted

    Since ASP.NET MVC3 RC2 I encounter a bug when posting values to a controller method of which one of the parameter is a nullable int.
    Steps to reproduce:

     I've created a test method

    [HttpPost]
    public ActionResult PostTest(string from, int? number, bool? formsearch)
    {
    return new ContentResult { Content = string.Format("{0}/{1}/{2}", from, number, formsearch) };
    }

    using jquery,  I create a Post request  

    $.post("http://localhost/mysite/test/posttest",{ from:"1//1/2009",number:"156",formsearch:true});

    the request (eg. in fiddler) shows clearly the values are being sent:

    from:1//1/2009
    number:156
    formsearch:true 

    but the result returned from this function is:

    1//1/2009//True

     If I change int? number to int number, the result is correct:

     1//1/2009/156/True

    In MVC3 RC1 this was working without any problems with the nullable int

    Update:  I don't seem to have the problem with a newly created MVC3 website. What could I have in my project that influence model binding to nullable int's? And why would there be a difference between RC1 and RC2? Anyone have suggestions for debugging this  model binding problem?

            [HttpPost]
            public ActionResult PostTest(string van, int soort, bool? FormSearch)
            {
                return new ContentResult { Content = string.Format("{0}/{1}/{2}", van, soort, FormSearch) };
            }        [HttpPost]
            public ActionResult PostTest(string van, int soort, bool? FormSearch)
            {
                return new ContentResult { Content = string.Format("{0}/{1}/{2}", van, soort, FormSearch) };
            }[
    Friday, December 10, 2010 6:15 PM

Answers

  • User-1660457439 posted

    Thank you for the reports.  We've confirmed that this is a bug that was introduced with RC2.  To work around this issue until a fix is available, please add the following line to your Global.asax file in the Application_Start method:

    ModelMetadataProviders.Current = new DataAnnotationsModelMetadataProvider();

    The bug exists in one of the caching systems in the MVC runtime, and the above line disables that particular cache.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Saturday, December 11, 2010 7:50 PM

All replies

  • User-797310475 posted

    Could you do a diff of your two projects and see what's different. I can't think of anything that would affect this, but maybe something will jump out? 

    Saturday, December 11, 2010 12:45 PM
  • User1205957345 posted

    Quite difficult to do, because one is a rather large existing application and the other is just a default MVC3 application...

    I've already tried to look at differences in config, routing, etc. but nothing at the moment seems to give an indication where to look. The strangest thing is it only happens for nullable int's so far.

    Saturday, December 11, 2010 1:45 PM
  • User996590589 posted

    I have exactly the same problem. I've got the following action method:

            public ActionResult Edit(long id, bool? saved)
            {
                var model = new CustomerEditModel
                    {
                        Categories = this._service.GetCategories(), 
                        Customer = this._service.GetCustomer(id), 
                        Saved = saved.HasValue && saved.Value
                    };
    
                return this.View(model);
            }

    Request.Url:

    + Url {http://tenant1.mpss.pl:8989/Dictionaries/Customer/Edit/1?saved=True} System.Uri


    Url {http://localhost:8989/Dictionaries/Customer/Edit/1?saved=True} System.Uri


    And what I get is an error in the ModelState dictionary for parameter saved with the following exception:

    System.InvalidOperationException: The parameter conversion from type 'System.String' to type 'System.Nullable`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]' failed. See the inner exception for more information. ---> System.Exception: True is not a valid value for Int32. ---> System.FormatException: Input string was not in a correct format.

       at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)

       at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)

       at System.ComponentModel.Int32Converter.FromString(String value, NumberFormatInfo formatInfo)

       at System.ComponentModel.BaseNumberConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)

       --- End of inner exception stack trace ---

       at System.ComponentModel.BaseNumberConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)

       at System.ComponentModel.NullableConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)

       at System.Web.Mvc.ValueProviderResult.ConvertSimpleType(CultureInfo culture, Object value, Type destinationType)

       --- End of inner exception stack trace ---

       at System.Web.Mvc.ValueProviderResult.ConvertSimpleType(CultureInfo culture, Object value, Type destinationType)

       at System.Web.Mvc.DefaultModelBinder.ConvertProviderResult(ModelStateDictionary modelState, String modelStateKey, ValueProviderResult valueProviderResult, Type destinationType)


    It looks like a bug to me. It basically tries to convert the value to int.. While the parameter type is Nullbable<bool>. What the heck?

    Another funny thing is that I was only able to debug this error once. Now when I debug I don't get this error. Once I stop debugging the error comes back and I get a validation error.. This is funny. It's running on IIS not Cassini.

    I also tried with Cassini - same luck. I get this error once in a while - usually when I change configurations and rebuild the solution. It's quite unpredictable. It somehow also affects Html.RenderPartial("PartialName", nullableParameter); The nullableParameter is sometimes parsed correctly and sometimes not. This is very wierd..

    Saturday, December 11, 2010 3:05 PM
  • User1858612482 posted

    rekna, is the default MVC 3 application you created also doing a jQuery post to the action? 

    Saturday, December 11, 2010 6:47 PM
  • User2133045845 posted

    I have encountered the same issue in my application.  Given a controller action method with this signature:

    [AcceptVerbs(HttpVerbs.Post)]

    public ActionResult SelectCompany(string name, int? connectionID)

    It looks like the ModelBinder is confused when trying to bind connectionID from a POST.  For some reason, when doing this, it thinks connectionID is ModelType = Nullable<bool>

    Obviously, this is wrong, so the model binding fails.  This was not happening in MVC3 RC1.  Any instructions on how to roll-back to RC1?

    Saturday, December 11, 2010 7:02 PM
  • User-1660457439 posted

    Thank you for the reports.  We've confirmed that this is a bug that was introduced with RC2.  To work around this issue until a fix is available, please add the following line to your Global.asax file in the Application_Start method:

    ModelMetadataProviders.Current = new DataAnnotationsModelMetadataProvider();

    The bug exists in one of the caching systems in the MVC runtime, and the above line disables that particular cache.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Saturday, December 11, 2010 7:50 PM
  • User996590589 posted

    Thanks, this workaround works for now.

    Still RC2 has some excellent features. Can't wait for RTM.

    Sunday, December 12, 2010 2:16 AM
  • User1205957345 posted

    Workaround indeed solves the problem... glad the bug was reproducible and the problem was found so quickly!

    Thx all.

    Sunday, December 12, 2010 11:34 AM
  • User-1539944883 posted

    It solved my problem, too. Originally I thought it had something to do with the model binding to a list, but this work-around fixes things up.

    I blogged about it here:

    http://www.distribucon.com/blog/ASPNETMVC3RC2BindingErrors.aspx

    Dan Miser

    Sunday, December 12, 2010 9:36 PM
  • User761847778 posted

    Please note: same problem with nullable enumerations as parameters

       public ActionResult(Gender? gender) {

       }

    (I know a nullable enumeration is *kinda* the same thing - but wanted to mention it to make sure they get fixed too!)

    Tuesday, December 14, 2010 12:54 AM