ASP.NET MVC5 ModelState 始终无效,同时不显示验证
ASP.NET MVC5 ModelState is always invalid while simultaneously not showing validations
我有一个带有一些验证规则的模型,例如最小字符串长度为 12。
public class Client{
[Required("ID Cannot be empty")]
[StringLength(12, ErrorMessage="ID must have 12 characters", MinimumLength = 12)]
public string Id { get; set; }
[Required("Name cannot be empty")]
[StringLength(60, ErrorMessage="Must be between 10 and 60 characters", MinimumLength = 10)]
public string FullName { get; set; }
[Required("Phone cannot be empty")]
[StringLength(9, ErrorMessage="Phone number must have 9 characters", MinimumLength = 9)]
public string PhoneNumber { get; set; }
[Required("Client needs a status")]
public bool PremiumStatus { get; set; }
}
这些规则适用于我拥有的 Registration
视图,这意味着我可以看到验证消息,如果模型无效,则不会注册该模型。
但是,在我的 Search/Edit 视图中,我应该能够在其中查找 ID 并修改返回的模型,none 的更改正在注册,并且在调试应用程序时,我看到 ModelState
对于模型总是无效的,但是,与此同时,我没有看到任何验证消息
@model MyApp.Models.Client
@{
ViewBag.Title = "MyApp"
}
@using(Html.BeginForm("Search", "Search", FormMethod.Post)){
Search for ID: @Html.TextBox("SearchId")
<input type="submit" value="Search"/>
}
@using(Html.BeginForm("EditClient", "Search", FormMethod.Post)){
@Html.LabelFor(m => m.Id)
@Html.DisplayFor(m => m.Id)
@Html.LabelFor(m => m.FullName)
@Html.EditorFor(m => m.FullName)
@Html.ValidationMessageFor(m => m.FullName)
@Html.LabelFor(m => m.PhoneNumber)
@Html.EditorFor(m => m.PhoneNumber)
@Html.ValidationMessageFor(m => m.PhoneNumber)
@Html.LabelFor(m => m.PremiumStatus)
@Html.EditorFor(m => m.PremiumStatus)
@Html.ValidationMessageFor(m => m.PremiumStatus)
<input type="submit" value="Save Changes"/>
}
请注意,我只想编辑姓名、phone 和状态。我不想编辑ID,所以它只是一个显示字段
现在在我的控制器上
public class SearchController : Controller {
public ActionResult Search() {
return View();
}
[HttpPost]
public ActionResult Search(string SearchId) {
//Searching my Session variable to retrieve Client item related to the code searched.
//I have validations in place in case the ID doesn't exist, but I'm not showing them to keep the code simple.
Client clientFound = (Client) Session[SearchId];
//Returns the view with the found model, populating all of the fields in the view.
return View("Search", clientFound)
}
[HttpPost]
//I just added these 2 annotations, but it wasn't working without them either
[ValidateAntiForgeryToken]
[ValidateInput(true)]
public ActionResult EditClient(Client model) {
if(ModelState.IsValid){
Session[model.Id] = model;
Debug.WriteLine("Client updated");
}
return RedirectToAction("Search");
}
}
通过设置断点,我可以看到一旦进入 EditClient
,模型确实具有分配给它的正确的、新近更新的属性。只是一直认为是无效的。如前所述,即使我从可编辑字段中删除所有内容,也不会收到显示它们无效的错误消息。
我认为您应该阅读 ASP.NET 中有关 ModelState 的更多信息。
这里有一些 Whosebug 的答案,可能与 Microsoft 官方文档一起提供帮助。
- https://docs.microsoft.com/en-us/aspnet/web-api/overview/formats-and-model-binding/model-validation-in-aspnet-web-api
- https://www.exceptionnotfound.net/asp-net-mvc-demystified-modelstate/
现在稍微解释一下你的问题。您按要求设置的字段之一没有数据类型或您的操作期望该字段的内容没有设置适当的数据类型。我自然会建议对于编辑和搜索功能,您应该使用其他形式的验证而不是 ModelState。因此,对于一个假设的解决方案,您的编辑视图自然应该具有模态视图,如果我 select 是一个详细信息,它会通过用户 ID 获取该用户信息向我显示当前数据。然后我可以提交我的编辑以及内容和用户 ID,然后这将使用 ID 匹配的新数据更新数据库,假设 ID 对于每个用户都是唯一的。
谢谢 请阅读分享的链接。
在您的 Client
模型上,属性 Id
是必需的。
因为它是必需的,所以您需要确保您有一个与您的 Id
属性 对应的输入字段,我找不到任何与之对应的 input
字段在你的 .cshtml
.
您可以包含一个 @Html.HiddenFor(m => m.Id)
(这是一个隐藏类型的输入字段),这样当您提交表单时 Id
仍将包含在 post 中。
我有一个带有一些验证规则的模型,例如最小字符串长度为 12。
public class Client{
[Required("ID Cannot be empty")]
[StringLength(12, ErrorMessage="ID must have 12 characters", MinimumLength = 12)]
public string Id { get; set; }
[Required("Name cannot be empty")]
[StringLength(60, ErrorMessage="Must be between 10 and 60 characters", MinimumLength = 10)]
public string FullName { get; set; }
[Required("Phone cannot be empty")]
[StringLength(9, ErrorMessage="Phone number must have 9 characters", MinimumLength = 9)]
public string PhoneNumber { get; set; }
[Required("Client needs a status")]
public bool PremiumStatus { get; set; }
}
这些规则适用于我拥有的 Registration
视图,这意味着我可以看到验证消息,如果模型无效,则不会注册该模型。
但是,在我的 Search/Edit 视图中,我应该能够在其中查找 ID 并修改返回的模型,none 的更改正在注册,并且在调试应用程序时,我看到 ModelState
对于模型总是无效的,但是,与此同时,我没有看到任何验证消息
@model MyApp.Models.Client
@{
ViewBag.Title = "MyApp"
}
@using(Html.BeginForm("Search", "Search", FormMethod.Post)){
Search for ID: @Html.TextBox("SearchId")
<input type="submit" value="Search"/>
}
@using(Html.BeginForm("EditClient", "Search", FormMethod.Post)){
@Html.LabelFor(m => m.Id)
@Html.DisplayFor(m => m.Id)
@Html.LabelFor(m => m.FullName)
@Html.EditorFor(m => m.FullName)
@Html.ValidationMessageFor(m => m.FullName)
@Html.LabelFor(m => m.PhoneNumber)
@Html.EditorFor(m => m.PhoneNumber)
@Html.ValidationMessageFor(m => m.PhoneNumber)
@Html.LabelFor(m => m.PremiumStatus)
@Html.EditorFor(m => m.PremiumStatus)
@Html.ValidationMessageFor(m => m.PremiumStatus)
<input type="submit" value="Save Changes"/>
}
请注意,我只想编辑姓名、phone 和状态。我不想编辑ID,所以它只是一个显示字段
现在在我的控制器上
public class SearchController : Controller {
public ActionResult Search() {
return View();
}
[HttpPost]
public ActionResult Search(string SearchId) {
//Searching my Session variable to retrieve Client item related to the code searched.
//I have validations in place in case the ID doesn't exist, but I'm not showing them to keep the code simple.
Client clientFound = (Client) Session[SearchId];
//Returns the view with the found model, populating all of the fields in the view.
return View("Search", clientFound)
}
[HttpPost]
//I just added these 2 annotations, but it wasn't working without them either
[ValidateAntiForgeryToken]
[ValidateInput(true)]
public ActionResult EditClient(Client model) {
if(ModelState.IsValid){
Session[model.Id] = model;
Debug.WriteLine("Client updated");
}
return RedirectToAction("Search");
}
}
通过设置断点,我可以看到一旦进入 EditClient
,模型确实具有分配给它的正确的、新近更新的属性。只是一直认为是无效的。如前所述,即使我从可编辑字段中删除所有内容,也不会收到显示它们无效的错误消息。
我认为您应该阅读 ASP.NET 中有关 ModelState 的更多信息。
这里有一些 Whosebug 的答案,可能与 Microsoft 官方文档一起提供帮助。
- https://docs.microsoft.com/en-us/aspnet/web-api/overview/formats-and-model-binding/model-validation-in-aspnet-web-api
- https://www.exceptionnotfound.net/asp-net-mvc-demystified-modelstate/
现在稍微解释一下你的问题。您按要求设置的字段之一没有数据类型或您的操作期望该字段的内容没有设置适当的数据类型。我自然会建议对于编辑和搜索功能,您应该使用其他形式的验证而不是 ModelState。因此,对于一个假设的解决方案,您的编辑视图自然应该具有模态视图,如果我 select 是一个详细信息,它会通过用户 ID 获取该用户信息向我显示当前数据。然后我可以提交我的编辑以及内容和用户 ID,然后这将使用 ID 匹配的新数据更新数据库,假设 ID 对于每个用户都是唯一的。
谢谢 请阅读分享的链接。
在您的 Client
模型上,属性 Id
是必需的。
因为它是必需的,所以您需要确保您有一个与您的 Id
属性 对应的输入字段,我找不到任何与之对应的 input
字段在你的 .cshtml
.
您可以包含一个 @Html.HiddenFor(m => m.Id)
(这是一个隐藏类型的输入字段),这样当您提交表单时 Id
仍将包含在 post 中。