#c# #asp.net-mvc #entity-framework
#c# #asp.net-mvc #entity-framework
Вопрос:
Я совершенно новичок в MVC и asp.net с Entity Framework, поэтому я уверен, что большая часть моих проблем связана с незнанием надлежащей терминологии для того, что я пытаюсь сделать.
У меня есть таблица / объект базы данных «Address», которая является адресом улицы. Вместо того, чтобы иметь поля уличного адреса в каждой сущности, с которой связан адрес, у меня просто есть столбец внешнего ключа, который указывает на правильный адрес в таблице адресов.
Для моей модели представления создания местоположения у меня есть следующее
public class LocationCreationViewModel
{
public address Address { get; set; }
[Key]
public location Location { get; set; }
}
Вероятно, стоит отметить, что эта модель представления «создана вручную», в то время как объекты-члены address и location управляются entity framework
Мое созданное представление содержит все данные о местоположении, а затем включает представление с частичным адресом, которое отображается с Html.Partial("_AddressCreate", Model.Location)
В данный момент происходит то, что LocationCreationViewModel, возвращаемый в Create(model)
функции, является LocationCreationViewModel равным null, или каждое из полей равно null. В любом случае, ни один из данных из представления не заполняется в модели представления.
Чего я хочу, так это чтобы я вернул 2 адреса, добавил их в таблицу адресов в базе данных, затем добавил свой заказ в базу данных заказов с полями адресов FK, указывающими на 2 вновь созданных адреса.
Я использую MVC5 и EF6 в Visual Studio 2017
Create.cshtml
@model MyWeb.Models.LocationCreationViewModel
@{
ViewBag.Title = "Create";
}
<h2>Create</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>location</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.Location.name, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Location.name, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Location.name, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Location.address, "address", htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownList("address", null, htmlAttributes: new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.Location.address, "", new { @class = "text-danger" })
</div>
</div>
@Html.Partial("_AddressPartial", Model.Address)
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
_AddressPartial.cshtml
@model MyWeb.Data.address
<div class="form-horizontal">
<h4>address</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.country, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.country, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.country, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.locality, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.locality, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.locality, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.postalCode, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.postalCode, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.postalCode, "", new { @class = "text-danger" })
</div>
</div>
</div>
LocationController::Создать
[MyWebAuthorize(MyWebRole = MyWebRole.Admin)]
public ActionResult Create()
{
ViewBag.address = new SelectList(db.addresses, "id", "country");
ViewBag.id = new SelectList(db.inventories, "locationID", "locationID");
LocationCreationViewModel model = new LocationCreationViewModel();
return View(model);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create( LocationCreationViewModel location)
{
if (ModelState.IsValid)
{
db.addresses.Add(location.Address); //null reference exception here
db.locations.Add(location.Location);
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
ViewBag.address = new SelectList(db.addresses, "id", "country", location.Location.address);
ViewBag.id = new SelectList(db.inventories, "locationID", "locationID", location.Location.id);
return View(location);
}
Комментарии:
1. Показать
_AddressCreate.cshtml
и просмотреть, гдеShipmentViewModel
создается. И действие контроллераCreate
, при котором выreturn View("...", new ShipmentViewModel());
2. @AlexanderYakushev я добавил немного кода.
Ответ №1:
Autobinder не удалось связать данные формы из-за имени поля Location
в модели представления. Я предполагаю, что это связано с тем, что Location
является частью маршрута страницы. Т.е. для LocationController маршрут будет /Location/Create
В любом случае переименование LocationCreationViewModel::Location
в LocationCreationViewModel::Locus
все исправило.