I have a problem with what should be a very simple ASP.NET MVC Create method.
After I populate data and submit the form in the Create view (and all the validation rules are passed), the instance of the model passed to the POST method will contain either null or 0 values for every field and ModelState.IsValid will return false.
I use Firebug to check the POST form parameters, and the submit action obviously has posted all the parameters from the fields. However, these parameters are not bound to the model passed to the POST method in the Controller, hence, the model (namely material in the code) contains null values in all field (as checked using Watch and breakpoints placed at the beginning of the POST method).
POST parameters from Firebug:
Content-Type: application/x-www-form-urlencoded Content-Length: 228 MaterialNoMass.MaterialNoMassID=9mmPlasterboard&MaterialNoMass.RoughnessTypeID=3&MaterialNoMass.Resistance=0.0560&MaterialNoMass.ThermalAbsorptance=0.09&MaterialNoMass.SolarAbsorptance=0.07&MaterialNoMass.VisibleAbsorptance=0.07
Create View:
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Database.Master"
Inherits="System.Web.Mvc.ViewPage<MvcDeepaWebApp.ViewModels.DatabaseSimpleMaterialViewModel>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<% Html.EnableClientValidation(); %>
<% using (Html.BeginForm())
{%>
<%: Html.ValidationSummary(true) %>
<fieldset>
<legend>Create MaterialNoMass</legend>
<%: Html.EditorFor(model => model.MaterialNoMass, new { RoughnessTypes = Model.RoughnessTypes })%>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
<% } %>
<div>
<%: Html.ActionLink("Back to List", "Index") %>
</div>
</asp:Content>
GET and POST methods of Create in Controller:
//
// GET: /DatabaseSimpleMaterial/Create
public ActionResult Create()
{
var viewModel = new DatabaseSimpleMaterialViewModel
{
MaterialNoMass = new MaterialNoMass(),
RoughnessTypes = deepaDB.RoughnessTypes.ToList()
};
return View(viewModel);
}
//
// POST: /DatabaseSimpleMaterial/Create
[HttpPost]
public ActionResult Create(MaterialNoMass material)
{
if (ModelState.IsValid)
开发者_开发知识库 {
MaterialAllType mt = new MaterialAllType();
mt.MatID = material.MaterialNoMassID;
mt.MatTypeID = deepaDB.MaterialTypes.Single(type => type.MatType == "SimpleMaterial").MatTypeID;
material.MatTypeID = mt.MatTypeID;
deepaDB.AddToMaterialAllTypes(mt);
deepaDB.AddToMaterialNoMasses(material);
deepaDB.SaveChanges();
return RedirectToAction("Index");
}
//Error occurred
var viewModel = new DatabaseSimpleMaterialViewModel
{
MaterialNoMass = material,
RoughnessTypes = deepaDB.RoughnessTypes.ToList()
};
return View(viewModel);
}
FYI, whenever a new MaterialNoMass is created, a new instance of MaterialAllType should also be created using the same ID of MaterialNoMass. I haven't even reached the stage of modifying the database yet, since the model binding seems to be not working.
I've used similar Create approach in other Controllers in the application and they all work fine except in this Controller. I've been having a hard time in debugging this for the past two days. Please help!
The problem comes from the fact that the model you are passing to the view is DatabaseSimpleMaterialViewModel
and inside the POST action you expect MaterialNoMass
. So make sure you use the correct prefix:
[HttpPost]
public ActionResult Create([Bind(Prefix="MaterialNoMass")]MaterialNoMass material)
I suppose that you editor template generates fields like this:
<input type="text" name="MaterialNoMass.MaterialNoMassID" value="" />
<input type="text" name="MaterialNoMass.RoughnessTypeID" value="" />
...
So you need to indicate the model binder that there's such prefix.
精彩评论