为什么在使用视图模型 (MVC) 时我的 ModelState 没有在控制器中更新?
Why isn't my ModelState updating in the controller when using a View Model (MVC)?
我正在通过 ajax 调用向视图上的控制器发送一些信息。控制器将 post 数据绑定到视图模型,如下所示:
UserController.cs
[HttpPost]
public ActionResult UserInfo(UserPositionVM userposvm)
{
//Check if user already exists in the database.
int? user_id = userposvm.User.userid;
var userindb = db.Users.Where(x => x.userid == user_id).FirstOrDefault();
/If the user does exist in the database, assign that User model to the view model.
if (userindb != null)
userposvm.User = userindb;
userposvm.User.Office = 3;
return PartialView(userposvm);
}
和我的视图模型...
UserPosition.cs
public class UserPositionVM
{
public Users User { get; set; }
public Positions Position { get; set; }
}
对于视图,我有这个:
AssignUser.cshtml
...
...
...
@Html.TextBoxFor(model => model.User.Office, new { @readonly = "readonly", @class = "form-control"})
@Model.User.Office
...
...
...
有趣的是,TextBoxFor 不填充值 (3),但 @Model.User.Office 填充。在做了一些研究之后,我发现它与 ModelState 有关。但是,我似乎无法在我的控制器 post 方法中更新 ModelState。
我已经尝试在我的函数开始时使用 ModelState.Clear(),以及在我的 return PartialView() 之前使用 UpdateModel(userposvm.User)。我看到另一个 post 与我的相似 (whosebug.com/questions/10248757),但它已经过时,我无法再访问其中一个答案中的博客。
我该如何解决这个问题?此外,在控制器内编辑模型值然后发送回视图的最佳方法是什么?
好吧,我现在觉得很傻,但我能够解决我的问题。首先,对于正在为此苦苦挣扎的任何其他人,我强烈建议您观看此视频:https://www.youtube.com/watch?v=9ul8oihM8hc&ab_channel=TechCBT
我没有完全理解 ModelState 和模型本身之间的关系。因此,通过从 post 数据绑定,在控制器中创建了 ModelState。 ModelState 背后的整个想法(据我所知)是您可以在视图中使用 HTML Helpers,然后它们将从 ModelState 中查找数据。
通常,当您提交表单时,如果您重定向到提交表单的同一页面,您在表单中输入的所有值都将被清除并重置。但是,如果您使用 HTML Helpers,它将检查 ModelState 中是否有任何值。如果是,他们会将相应的值加载到字段中。
事实是,ModelState 实际上优先于 Model 本身。换句话说,HTML Helper 将首先检查 ModelState。如果它找到具有值的相应键,它将加载该数据。如果它在 ModelState 中没有找到任何东西,它将引用该模型。这正是我的 TextBoxFor 加载的值与模型中的值不同的原因;因为它在 ModelState 中找到了一些东西,所以它完全忽略了 Model。
因此,使用 ModelState.Clear() 确实 解决了这个问题。但是,我在执行 ModelState.Clear() 时没有看到结果的原因是(令人尴尬的是)我在视图中错误地指定了帮助。所以它只是显示 null 而不是 3。希望这可以帮助其他遇到类似问题的人!
我正在通过 ajax 调用向视图上的控制器发送一些信息。控制器将 post 数据绑定到视图模型,如下所示:
UserController.cs
[HttpPost]
public ActionResult UserInfo(UserPositionVM userposvm)
{
//Check if user already exists in the database.
int? user_id = userposvm.User.userid;
var userindb = db.Users.Where(x => x.userid == user_id).FirstOrDefault();
/If the user does exist in the database, assign that User model to the view model.
if (userindb != null)
userposvm.User = userindb;
userposvm.User.Office = 3;
return PartialView(userposvm);
}
和我的视图模型...
UserPosition.cs
public class UserPositionVM
{
public Users User { get; set; }
public Positions Position { get; set; }
}
对于视图,我有这个:
AssignUser.cshtml
...
...
...
@Html.TextBoxFor(model => model.User.Office, new { @readonly = "readonly", @class = "form-control"})
@Model.User.Office
...
...
...
有趣的是,TextBoxFor 不填充值 (3),但 @Model.User.Office 填充。在做了一些研究之后,我发现它与 ModelState 有关。但是,我似乎无法在我的控制器 post 方法中更新 ModelState。
我已经尝试在我的函数开始时使用 ModelState.Clear(),以及在我的 return PartialView() 之前使用 UpdateModel(userposvm.User)。我看到另一个 post 与我的相似 (whosebug.com/questions/10248757),但它已经过时,我无法再访问其中一个答案中的博客。
我该如何解决这个问题?此外,在控制器内编辑模型值然后发送回视图的最佳方法是什么?
好吧,我现在觉得很傻,但我能够解决我的问题。首先,对于正在为此苦苦挣扎的任何其他人,我强烈建议您观看此视频:https://www.youtube.com/watch?v=9ul8oihM8hc&ab_channel=TechCBT
我没有完全理解 ModelState 和模型本身之间的关系。因此,通过从 post 数据绑定,在控制器中创建了 ModelState。 ModelState 背后的整个想法(据我所知)是您可以在视图中使用 HTML Helpers,然后它们将从 ModelState 中查找数据。
通常,当您提交表单时,如果您重定向到提交表单的同一页面,您在表单中输入的所有值都将被清除并重置。但是,如果您使用 HTML Helpers,它将检查 ModelState 中是否有任何值。如果是,他们会将相应的值加载到字段中。
事实是,ModelState 实际上优先于 Model 本身。换句话说,HTML Helper 将首先检查 ModelState。如果它找到具有值的相应键,它将加载该数据。如果它在 ModelState 中没有找到任何东西,它将引用该模型。这正是我的 TextBoxFor 加载的值与模型中的值不同的原因;因为它在 ModelState 中找到了一些东西,所以它完全忽略了 Model。
因此,使用 ModelState.Clear() 确实 解决了这个问题。但是,我在执行 ModelState.Clear() 时没有看到结果的原因是(令人尴尬的是)我在视图中错误地指定了帮助。所以它只是显示 null 而不是 3。希望这可以帮助其他遇到类似问题的人!