Coffeehouse Thread

8 posts

Advanced MVC 3 with Brad Wilson - non class models

Back to Forum: Coffeehouse
  • User profile image
    SallyMeander

    I am adapting the NonClassModels area of Brad Wilson's Advanced MVCConf2011 project. Everything works fine for me when my dictionary is <string,string> but when I change it to <string,object> I get an error in my call to

    OnModelUpdated(controllerContext, bindingContext); within the DictionaryModelBinder.

    The error is

    Unable to cast object of type 'System.String[]' to type 'System.String'.

     

    [InvalidCastException: Unable to cast object of type 'System.String[]' to type 'System.String'.]   System.ComponentModel.DataAnnotations.StringLengthAttribute.IsValid(Object value) +46   System.ComponentModel.DataAnnotations.ValidationAttribute.IsValid(Object value, ValidationContext validationContext) +115   System.ComponentModel.DataAnnotations.ValidationAttribute.GetValidationResult(Object value, ValidationContext validationContext) +29   System.Web.Mvc.<Validate>d__1.MoveNext() +161   System.Web.Mvc.<Validate>d__5.MoveNext() +311   System.Web.Mvc.DefaultModelBinder.OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext) +136   MvcConf2011.Areas.NonClassModels.DictionaryModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) in c:\Projects\EnterpriseManagementSamples\advanced-mvc-3 - Copy\Areas\NonClassModels\Utility\ModelBinder\DictionaryModelBinder.cs:51 

     

    Any ideas? I have not been able to successfully get the source code into the project to debug it.

  • User profile image
    SallyMeander

    I am new to both mvc and c#. I found that the code was failing during string length validation. If I remove that annotation it no longer fails.

  • User profile image
    kettch

    @SallyMeander: In the case of a casting problem, you'll have to walk up and down the code to see where that object is used both before and after the line of code you changed. I'm not familiar with that project. It's a bit old and from a specific presentation, so there might not be anybody here who knows it either.

    You might have better luck on stackoverflow.com, which is a development Q&A site.

  • User profile image
    PopeDai

    Out of curiosity, what do you hope to achieve by using a Dictionary instead of a class? I don't see any real advantage to using it; surely the RAD gains by losing typing would be lost in the pains of debugging and key-name management?

  • User profile image
    cheong

    @SallyMeander:I think it could be a missing model binder to convert an array.

    Btw, my company's MVC web application needs to add 2 custom derivatives of DefaultModelBinder to make it work for us (because it won't handle number with thousand seperator). Maybe you should write your own ModelBinder too to work around this.

    The key would be to add the following check:

    if (bindingContext.ValueProvider.GetValue(bindingContext.ModelName).RawValue is Array)

    I'll leave it to you to figure out the remaing code to be written.

    Recent Achievement unlocked: Code Avenger Tier 4/6: You see dead program. A lot!
    Last modified
  • User profile image
    PopeDai

    , cheong wrote

    @SallyMeander:I think it could be a missing model binder to convert an array.

    Btw, my company's MVC web application needs to add 2 custom derivatives of DefaultModelBinder to make it work for us (because it won't handle number with thousand seperator). Maybe you should write your own ModelBinder too to work around this.

    I'm not of the opinion that input format parsing and acceptance should be done with a ModelBinder - you can do this directly at the Model with property attributes. Generally speaking you never need to derive a new ModelBinder.

  • User profile image
    cheong

    @PopeDai: Not if you have hundreds of HttpHandler written already to accept numbers, and already have some other applications/web applications deployed to consuming them already. You can't just change the function signatures.

    Btw, if your ModelBinder cannot handle array that has single element (much like a recent case where I need to read a range in Excel that should return 2-dimensional array of objects but Excel just return me string because in that reported case the range only contains single cell), you'd need to write your way to consume it yourself.

    As a seperate rant, I'd pretty much like Excel to always return 2-dimensional array if 2 reference is specified, even if they point to the same cell. However, I understand this will break other code so is not likely to happen. Now I wonder where's time machine when you need it. Tongue Out

    Recent Achievement unlocked: Code Avenger Tier 4/6: You see dead program. A lot!
    Last modified
  • User profile image
    SallyMeander

     @kettch Thanks for the hints. I will try stackoverflow.com 

    @PopeDai: We are trying to create a very flexible system so that when there are changes to the models we won' t have to change our code, just send new models with annotations to the webapp at run time.There are thousands of data points.

    @cheong Thanks for the ideas. I thought about a custom model binder but this project is so complex for a newbie, never having coded in C# before!!, I was not sure how best to fit it in. Instead I played with the annotation DataTypeName and found that if I set it to ("Boolean") it created a checkbox! Wow and that is not even listed as an option for this field. With that I changed my dictionary back to <string, string> from <string, object> and now the StringLength annotation works as well.

    Just one solution at the very beginning of a very long road to this model.

    The next few tasks are preserving the fifo order of the key, value pairs in the model (they come out in a different order in the view after saving changes), and figuring out how to handle radio buttons and show disabled (non-editable) fields.

     

Comments closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums, or Contact Us and let us know.