ASP .NET MVC - не удается обновить данные один на один - PullRequest
0 голосов
/ 24 октября 2018

Я создаю веб-приложение с использованием ASP .NET MVC5 и EF6.У меня взаимно-однозначное отношение, определенное следующим образом:

public class Client 
{
  public int ClientId { get; set; }  
  [Required]
  public string Name { get; set; }

  public Address Address { get; set; }
}

public class Address 
{
  [ForeignKey("Client")]
  public int AddressId { get; set; }  
  [Required]
  public string StreetName { get; set; }

  public Client Client { get; set; }
}

Где адрес является зависимым концом.После включения миграции и обновления базы данных создаются две таблицы, в которых таблица адресов содержит столбец ClientId в результате использования внешнего ключа.

Затем я приступил к генерацииКонтроллеры и Представления для этих классов.

Для адреса я пытаюсь изменить методы и представления Create / Edit, чтобы иметь возможность добавить новый адрес и связать его с существующим клиентом, что в точности и делается в этом руководстве:

https://docs.microsoft.com/en-us/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application

Мой AddressController был настроен именно так, как предлагается в учебном пособии, а также соответствующие представления.Но при доступе к странице «Создать» во время работы веб-приложения я могу написать название улицы и выбрать из выпадающего списка имя для клиента (что я и хочу, отображать имя клиента, а не идентификатор).

При нажатии на кнопку создания я получаю следующую ошибку:

Оператор INSERT конфликтует с ограничением FOREIGN KEY "FK_dbo.Addresses_dbo.Clients_AddressId".Конфликт произошел в базе данных «myDb», таблице «dbo.Clients», столбце «ClientId».Оператор был прекращен.

Это заставляет меня думать, что ClientId внешнего ключа не обновляется, как это должно было быть, путем выбора имени в раскрывающемся списке.Я пытался добавить новых клиентов без связанных с ними адресов, но даже при выборе клиента без связанного адреса ошибка сохраняется.

Я также знаю, что в идеале в раскрывающемся списке должны отображаться только клиенты без какого-либо адреса.связан с ними, но я не знаю, как это сделать.

Поскольку я следовал каждому этапу упомянутого урока, я действительно не знаю, что я делаю неправильно.

Любая помощь будет чрезвычайно признательна!Если потребуется опубликовать больше кода, я сделаю это, просто не сделал этого, чтобы сократить этот уже длинный пост.

Обновить код

AddressesController.cs

public class AddressesController : Controller
    {
        private ApplicationDbContext db = new ApplicationDbContext();

        // GET: Addresses
        public ActionResult Index()
        {
            var addresses = db.Addresses.Include(m => m.Client);
            return View(addresses.ToList());
        }

        // GET: Addresses/Details/5
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Address address = db.Addresses.Find(id);
            if (address == null)
            {
                return HttpNotFound();
            }
            return View(address);
        }

    // GET: Address/Create
        public ActionResult Create()
        {
            PopulateClientsDropDownList(); 
            return View();
        }

        // POST: Addresses/Create
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create([Bind(Include = "AddressId,StreetName,ClientId")] Address address)
        {
            try
            {
                if (ModelState.IsValid)
                {

                    db.Addresses.Add(addresses);
                    db.SaveChanges();
                    return RedirectToAction("Index");
                }
            }
            catch (DataException dex)
            {

                ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator.");
                ErrorSignal.FromCurrentContext().Raise(dex);
            }
            PopulateClientsDropDownList(address.ClientId);
        return View(address);
        }

    // GET: Addresses/Edit/5
        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

        Address address = db.Address.Find(id);
            if (address == null)
            {
                return HttpNotFound();
            }
            PopulateClientsDropDownList(address.ClientId); 

            return View(address);
        }

        // POST: Addresses/Edit/5
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost, ActionName("Edit")]
        [ValidateAntiForgeryToken]
        public ActionResult EditPost(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            var addressToUpdate = db.Addresses.Find(id);
            if (TryUpdateModel(addressToUpdate, "",
                new string[] { "StreetName", "ClientId" }))
            {
                try
                {
                    db.SaveChanges();
                    return RedirectToAction("Index");
                }
                catch (RetryLimitExceededException dex)
                {
                    ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator.");
                    ErrorSignal.FromCurrentContext().Raise(dex);
                }
            }
            PopulateAddressesDropDownList(addressToUpdate.ClientId);
            return View(addressToUpdate);
        }

    private void PopulateClientsDropDownList(object selectedClient = null)
        {
            var clientsQuery = from d in db.Clients
                               orderby d.Name
                               select d;
            ViewBag.ClientId = new SelectList(clientsQuery, "ClientId", "Name", selectedClient);
        }
}

Create.cshtml (укорочено)

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>Addresses</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        @*<div class="form-group">
                @Html.LabelFor(model => model.AddressId, "AddressId", htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.DropDownList("AddressId", null, htmlAttributes: new { @class = "form-control" })
                    @Html.ValidationMessageFor(model => model.AddressId, "", new { @class = "text-danger" })
                </div>
            </div>*@

        <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">
            <label class="control-label col-md-2" for="ClientId">Client Name</label>
            <div class="col-md-10"> 
                @Html.DropDownList("ClientId", null, htmlAttributes: new { @class = "form-control" })
                @Html.ValidationMessageFor(model => model.ClientId, "", new { @class = "text-danger" })
            </div>
        </div>

        <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>
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...