注意:請忽略密碼存盤不安全的事實;這個專案只是為了我自己的學習目的,我以后會解決這個問題。
我有三個模型,Account、AccountType 和 Person:
public class Account
{
[Key]
public int AccountID { get; set; }
[ForeignKey("AccountType")]
public int AccountTypeID { get; set; }
[ForeignKey("Person")]
public int PersonID { get; set; }
[Required]
public string Username { get; set; }
[Required]
public string Password { get; set; }
[Required]
public DateOnly DateCreated { get; set; } = DateOnly.FromDateTime(DateTime.Now);
[Required]
public DateOnly DateModified { get; set; } = DateOnly.FromDateTime(DateTime.Now);
public virtual AccountType AccountType { get; set; }
public virtual Person Person { get; set; }
}
public class AccountType
{
[Key]
public int AccountTypeID { get; set; }
[Required]
public string AccountTypeName { get; set; }
}
public class Person
{
[Key]
public int PersonID { get; set; }
[Required]
[DisplayName("First Name")]
public string FirstName { get; set; }
[Required(AllowEmptyStrings = true)]
[DisplayFormat(ConvertEmptyStringToNull = false)]
[DisplayName("Middle Name")]
public string MiddleName { get; set; }
[Required]
[DisplayName("Last Name")]
public string LastName { get; set; }
[Required]
[DisplayName("Email")]
public string Email { get; set; }
[Required(AllowEmptyStrings = true)]
[DisplayFormat(ConvertEmptyStringToNull = false)]
[DisplayName("Phone")]
public string Phone { get; set; }
[Required]
public DateOnly CreatedDate { get; set; } = DateOnly.FromDateTime(DateTime.Now);
[Required]
public DateOnly ModifiedDate { get; set; } = DateOnly.FromDateTime(DateTime.Now);
}
因為我想在一個視圖中使用所有這三個模型,所以我為它們創建了一個注冊視圖模型:
public class Register
{
public List<SelectListItem> AccountTypes { get; set; }
public Account Account { get; set; }
public Person Person { get; set; }
}
這是相關控制器的 GET 操作方法,它為視圖提供服務:
public IActionResult Register()
{
var Register = new Register();
Register.AccountTypes = _db.AccountTypes.Select(accType => new SelectListItem
{
Value = accType.AccountTypeID.ToString(),
Text = accType.AccountTypeName
}).ToList();
return View(Register);
}
這是注冊視圖本身:
@model Register
<form method="post">
<div class="row mb-2">
<div class="col-12">
<select asp-for="Account.AccountTypeID"
asp-items="Model.AccountTypes"
class="form-select"
aria-label="Default select example"
></select>
</div>
</div>
<div class="row mb-2">
<div class="col-12">
<label asp-for="Account.Username" class="d-block"></label>
<input asp-for="Account.Username" class="w-100" />
<span asp-validation-for="Account.Username" class="text-danger"></span>
</div>
<div class="col-12">
<label asp-for="Account.Password" class="d-block"></label>
<input asp-for="Account.Password" class="w-100" />
<span asp-validation-for="Account.Password" class="text-danger"></span>
</div>
</div>
<partial name="/Views/Person/_Create.cshtml" for="Person" />
<button type="submit" class="btn btn-primary">Create</button>
</form>
我現在正處于撰寫控制器的 POST 操作方法的階段,目標是將視圖中的系結欄位提交到資料庫中,但遇到了一些麻煩:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Register(Register Register)
{
if (ModelState.IsValid)
{
_db.Persons.Add(Register.Person);
_db.Accounts.Add(Register.Account);
_db.SaveChanges();
}
return View(Register);
}
當我ModelState.IsValid在線上放置一個標記時,我看到它是false. 我知道這是因為 3 個模型欄位具有空值/無效值:
AccountTypesAccount.AccountTypeAccount.Person
我需要AccountTypes在注冊模型中顯示視圖的下拉/選擇欄位中的帳戶型別串列。然后,Account.AccountType并且Account.Person也是必要的,因為它們為物體建立了表之間的關系。所以,我想我不能從模型中洗掉這些欄位。
我考慮過以某種方式從驗證程序中排除這些特定欄位,同時將它們保留在模型中,但我不確定如何去做。此外,我有一種揮之不去的感覺,可能有一種更好的方法來處理我不知道的整個程序。
那么,讓 ModelState 接受 POST 注冊請求的最正確方法是什么?
uj5u.com熱心網友回復:
顯然你正在使用net6。你有兩個選擇,讓這個屬性可以為空(也許還有更多)
public virtual AccountType? AccountType { get; set; }
public virtual Person? Person { get; set; }
或者為了防止將來其他類發生這種情況,您可以從專案配置中洗掉 Nullable
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<!--<Nullable>enable</Nullable>-->
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
uj5u.com熱心網友回復:
在您的人員模型中,有幾個欄位被標記為必需屬性。由于此 ModelState 始終為 false,因為這些欄位需要值和視圖或控制器(GET 呼叫)不提供它們。如果可能,您可以洗掉所需欄位或為沒有必填欄位的人員創建單獨的模型。

然后要選擇 AccountType,您需要像這樣更改注冊模型。
public class Register
{
public Register()
{
Person = new Person();
Account = new Account();
}
public int AccountTypeId { get; set; }
public List<SelectListItem> AccountTypes { get; set; }
public Account Account { get; set; }
public Person Person { get; set; }
}
并像這樣在視圖中更改選擇。
<select asp-for="AccountTypeId"
asp-items="Model.AccountTypes"
class="form-select"
aria-label="Default select example"
></select>
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/452690.html
標籤:。网 asp.net-mvc 实体框架 外键 模型状态
