Reputation: 6693
Using below models
public class State
{
public int StateId { get; set; }
public string Code { get; set; }
public string Name { get; set; }
}
public class City
{
public int CityId { get; set; }
public string Name { get; set; }
public State state { get; set; }
}
and following View
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>City</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.HiddenFor(model => model.CityId)
@Html.HiddenFor(model => model.state.StateId)
@Html.HiddenFor(model => model.state.Name)
@Html.HiddenFor(model => model.state.Code)
<div class="form-group">
@Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
I see the State
is NULL
in my controller
public ActionResult Edit([Bind(Include = "CityId,Name")] City city)
{
// City.State is NULL and ModelSAtate.IsValid is FALSE
if (ModelState.IsValid)
{
db.Entry(city).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(city);
}
By this mean, City.State
is NULL
.
I know the workaround to make ModelState.IsValid
to TRUE
but I like to know the right way for hanlding object property in MVC View.
Upvotes: 3
Views: 1107
Reputation: 576
Whenever you try to process a request from your view to your controller, MVC Routing tries to identify which controller action to invoke according to your route configuration. This job is assigned to the ControllerActionInvoker. After successfully identifying which action to invoke, now the default model binder takes control of binding the model correctly.
The Default Model Binding(DefaultModelBinder) works in the following order :-
Request.Form - Values submitted in the form
RouteData.Values - Route values e.g. id in /Employee/Edit/{id}
Request.QueryString - Data extracted from the query string portion of the URL
Request.Files - Uploaded Files
There are ways to customize your binding behaviour, you may find this article interesting - https://mono.software/2017/02/09/model-binding-asp-net-mvc/
But for your problem, the given answer by @Marusyk is sufficient enough. Happy coding...
Upvotes: 0
Reputation: 24619
You should to add also these hidden property if you want to catch State
entity in your action as a part of City
@Html.HiddenFor(model => model.state.StateId)
@Html.HiddenFor(model => model.state.Name)
@Html.HiddenFor(model => model.state.Code)
EDIT:
I also had to remove the Bind()
section so my action look like
public ActionResult Edit(City city)
Upvotes: 3