Lorenzo
Lorenzo

Reputation: 29427

Model Binder very strange error

I have a problem with the default Model Binder which behave in a very strange way. I am trying to POST some data to a controller action and expect that these data field would bound to a view model class I have coded.

This is the View model class:

public class CashRegisterViewModel
{
    [Required]
    [Display( Name = "CashRegisterID" )]
    public int CashRegisterID { get; set; }

    [Required]
    [Display( Name = "RegisterCode" )]
    public string RegisterCode { get; set; }

    [Required( AllowEmptyStrings = true )]
    [Display( Name = "Cash model" )]
    public string Model { get; set; }

    [Required( AllowEmptyStrings = true )]
    [Display( Name = "Concept" )]
    public string Concept { get; set; }

    [Required( AllowEmptyStrings = true )]
    [Display( Name = "IP Address" )]
    public string IPAddress { get; set; }

    [Required( AllowEmptyStrings = true )]
    [Display( Name = "External Cash Register Code" )]
    public string ExternalCashRegisterCode { get; set; }

    [Required]
    [Display( Name = "PoS ID" )]
    public int PoSID { get; set; }
}

This is the controller action method

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SaveCashRegister( CashRegisterViewModel model ) {
    if ( ModelState.IsValid ) {
        [...]
    }
}

Looking at Fiddler this is the request that get to the server

Fiddler request

However when I run the code ModelState.IsValid is always false and if I look into the ModelState I can see the following error

{"The parameter conversion from type 'System.String' to type 'MyProject.ViewModel.Common.CashRegisterViewModel' failed because no type converter can convert between these types."}

Can someone give any suggestion on this behaviour?

Upvotes: 0

Views: 156

Answers (1)

user3559349
user3559349

Reputation:

The problem is that your view model contains a property name model and your POST method has a parameter of the same name. Change the parameter to anything other that a property name of your model and it will be correctly bound. e.g.

public ActionResult SaveCashRegister(CashRegisterViewModel viewModel)

What is happening internally is that your form collection contains a value model:"IBM 4846E65". The DefaultModelBinder then looks for a property named model to set its value. If finds your parameter and so it tries CashRegisterViewModel model = "IBM 4846E65"; which of course fails (you cant assign a string to a complex object) and the binding fails (and your model is null)

Upvotes: 2

Related Questions