我正在構建 ASP.NET MVC 專案,關于這個主題的所有其他帖子都沒有幫助我。我有 2 個模型,客戶端和城市。
public class Client
{
[Key]
public int Id { get; set; }
public string Surname { get; set; }
public string Name { get; set; }
public City City { get; set; }
}
public class City
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
}
當我想創建一個客戶端時,有一個例外沒有型別為“IEnumerable”的 ViewData 專案具有鍵“City”。
這是我的獲取和發布方法
private readonly ApplicationDbContext _context;
private List<City> _cities;
public ClientsController(ApplicationDbContext context)
{
_context = context;
}
// GET: Clients/Create
public IActionResult Create()
{
if (_context.City != null) _cities = _context.City.ToList();
ViewBag.Cities = new SelectList(_cities, "Id", "Name");
return View();
}
// POST: Clients/Create
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Id,Surname,Name,Patronymic,Telephone,City,Adress,SeriaNumberPassport,IdentificalCode")]
Client client)
{
if (ModelState.IsValid)
{
_context.Add(client);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(client);
}
并查看代碼:
<div class="form-group" mb-3>
<label asp-for="City" class="control-label"></label>
@Html.DropDownListFor(model => model.City, ViewBag.Cities as SelectList, new { @class = "form-select" })
</div>
資料顯示正確,但我無法創建客戶端。
uj5u.com熱心網友回復:
認為ModelState.IsValidis false,因此它回傳到CreateView 而不是重定向到Indexview (成功插入的流程Client)。
ViewBag.Cities而對于插入失敗的情況,您在回傳 View 之前沒有提供值Create(檢查Create方法[HttpPost])。
談論為什么ModelState.IsValid是false,您傳遞的型別存在沖突,即CityId型別int與型別的City屬性City。
更新:
建議創建和使用 ViewModel 類而不是 Model。主要原因是我們可以設計屬性僅用于查看、創建/編輯目的的類。
暴露 Model 類是不安全的,因為用戶會知道你的資料庫物體是什么樣子的。
但是使用 ViewModel 的麻煩在于您需要手動或使用反射將屬性值從 ViewModel 映射到 Model。當然,也有一些開源庫可以自動進行映射,例如AutoMapper。
這些是您需要為修復執行的步驟:
模型
- 添加
CityId外鍵屬性。
public class Client
{
[Key]
public int Id { get; set; }
public string Surname { get; set; }
public string Name { get; set; }
public int CityId { get; set; } // Add this foreign key property
public City City { get; set; }
}
注意:如果您使用 Entity Framework Code First 方法,則需要通過命令創建遷移并更新資料庫以進行此更改。
視圖模型
使用創建客戶端所需的屬性創建 ViewModel 類。
public class CreateClientModel
{
public string Surname { get; set; }
public string Name { get; set; }
public int CityId { get; set; }
// Other properties that needed
}
看法
2.1。將 更改@model為CreateClientModel。2.2. 使用model.CityId而不是model.City. 該CityId屬性用于傳遞所選城市的 ID。
@model CreateClientModel
<div class="form-group" mb-3>
<label asp-for="CityId" class="control-label"></label>
@Html.DropDownListFor(model => model.CityId, ViewBag.Cities as SelectList, new { @class = "form-select" })
</div>
控制器
3.1。替換City為CityIdinBind屬性。(添加基于 的屬性CreateClientModel)。
3.2. 用作CreateClientModel請求正文。
3.3. ViewBag.Cities在回傳到is caseCreate的視圖之前初始化值。ModelState.IsValidfalse
public IActionResult Create()
{
if (_context.City != null) _cities = _context.City.ToList();
ViewBag.Cities = new SelectList(_cities, "Id", "Name");
return View(new CreateClientModel());
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Surname,Name,CityId")]
ClientClientModel client)
{
if (ModelState.IsValid)
{
// Perform mapping from CreateClientModel to
_context.Add(new Client
{
Surname = client.Surname,
Name = client.Name,
CityId = client.CityId
// Other properties
});
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
// Initialize ViewBag.Cities value
if (_context.City != null) _cities = _context.City.ToList();
ViewBag.Cities = new SelectList(_cities, "Id", "Name");
return View(client);
}
建議閱讀并遵循與您的場景類似的本教程:
教程:更新相關資料 - 帶有 EF Core 的 ASP.NET MVC
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/491195.html
標籤:C# 网 asp.net-mvc asp.net 核心
上一篇:一些但不是其他的SQL聚合更新
下一篇:如何創建資料庫優先方法精確類專案
