I have a controller, which returns a view passing in a view model, which has properties required for display of the view (Drop-down select item lists etc).
But when I post it to the server, I have a different model class, which has the selected value of those dropdowns. In my HttpPost controller action, I check the (ModelState.IsValid), before doing any processing, but when it is false, I 'return View(model)' back.
But since the view is bound to the ViewModel, and my Post action, is accepting the actual model, I get an error 'The model item passed into the dictionary is of type 'Model', but this dictionary requires a model item of type 'ViewModel', when I submit the form, and the validation error to show up on the view.
How do I solve this? What is the best practice for using strongly typed views, passing in the view model, but when submitting to a different model?
Code:
public ActionResult Buy()
{
BuyVM buyVM = GetBuyVM();
return View(buyVM);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Buy(BuyModel model)
{
if (ModelState.IsValid)
{
// Do Procesing
return View("Success");
}
return View(model);
}
public class BuyVM
{
public SelectList PurchaseDateList { get; set; }
public SelectList BedroomsList { get; set; }
public SelectList StoriesList { get; set; }
[Required]
public string SquareFootage { get; set; }
[Required]
public string PreferredCityLocations { get; set; }
public string AdditionalInfo { get; set; }
}
public class BuyModel
{
public string PurchaseDateList { get; set; }
public string BedroomsList { get; set; }
public string StoriesList { get; set; }
public string SquareFootage { get; set; }
public string PreferredCityLocations { get; set; }
public string AdditionalInfo { get; set; }
}
private static BuyVM GetBuyVM()
{
BuyVM buyVM = new BuyVM();
buyVM.PurchaseDateList = new SelectList(new[] { "Immediately", "1 to 3 months", "4 to 6 months", "More than 6 months" });
buyVM.BedroomsList = new SelectList(new[] { "1", "2", "3", "4", "5+" });
buyVM.StoriesList = new SelectList(new[] { "1", "2", "Does not matter" });
return buyVM;
}
Buy.cshtml
@model Models.BuyVM
// html
@Html.DropDownListFor(m => m.PurchaseDateList, Model.PurchaseDateList, new { @class = "form-control" })
@Html.DropDownListFor(m => m.BedroomsList, Model.BedroomsList, new { @class = "form-control" })
So when I return the View(model) back, in the HTTPPost if there were validation errors (JQueryVal), I am trying to display the validation errors, if I pass the model back to the view. But I have this type mismatch.
public async Task<ActionResult> Buy(BuyVM model)
(notBuyModel
) but youBuyVM
view model appears be be missing a lot of properties - you haveSelectList
's for a number of properties by no corresponding property to bind to. – user3559349