Asp.net mvc 4 MVC 4 ModelState无效,因为它正在尝试自动填充值而不接受新值
我有一个评论部分。在视图中,只有一个注释编辑器框Asp.net mvc 4 MVC 4 ModelState无效,因为它正在尝试自动填充值而不接受新值,asp.net-mvc-4,modelstate,modelstatedictionary,Asp.net Mvc 4,Modelstate,Modelstatedictionary,我有一个评论部分。在视图中,只有一个注释编辑器框 @using (Html.BeginForm(new { courseID = @ViewBag.courseID, userName = @User.Identity.Name })) { @Html.ValidationSummary(true) <div class="NewComment"> <div class="editor-field"> @Html.
@using (Html.BeginForm(new { courseID = @ViewBag.courseID, userName = @User.Identity.Name }))
{
@Html.ValidationSummary(true)
<div class="NewComment">
<div class="editor-field">
@Html.TextAreaFor(model => model.CommentText, new { maxLength = 500})
@Html.ValidationMessageFor(model => model.CommentText)
</div>
<input type="submit" class="PostComment" value="Post Comment" />
<div id="Counter" class="CommentCounter"/>
</div>
}
问题就发生在这里。在我实际执行工作并设置它之前,模型试图使用userName
参数作为courseComment.userName
的值。设置后,ModelState
不会更改
例如,domain\abc123
被传递到post方法中,并在ModelState
中为UserName
设置。我做了一些工作,将userName
更改为abc123
,并找到具有所述名称的用户的链接ID,比如ID=1,然后将其插入课程注释。userName
ModelState
仍将域\abc123
保留在其中,模型保持无效
现在,这是最初的工作,然后我改变了底层数据库,主要是列名和一些关系
我的解决方案。
从post方法接收用户名时移动
[HttpPost]
public ActionResult AddComment(CourseComment coursecomment, int courseID)
{
coursecomment.CommentDate = System.DateTime.Now;
coursecomment.CourseID = courseID;
coursecomment.UserName = db.Users.FirstOrDefault(u => u.UserName == userName).UserID; //Moved
if (ModelState.IsValid)
{
db.CourseComments.AddObject(coursecomment);
db.SaveChanges();
}
return RedirectToAction("Details", "Course", new { courseID = courseID });
}
获取方法
[HttpGet]
public JsonResult GetUserName(string userName)
{
var ret = db.Users.FirstOrDefault(u => u.UserName == userName).UserID;
return Json(ret, JsonRequestBehavior.AllowGet);
}
然后将视图更改为
@Html.HiddenFor(model => model.UserName)
....
<script type="text/javascript">
$(function () {
var userName = '@User.Identity.Name.Split('\\')[1]';
$.ajax({
url: '@Url.Action("GetUserName", "CourseComment")',
data: { userName: userName },
type: 'get'
}).done(function (data) {
$('#UserName').val(data);
});
});
@Html.HiddenFor(model=>model.UserName)
....
$(函数(){
var userName='@User.Identity.Name.Split('\\')[1]';
$.ajax({
url:'@url.Action(“GetUserName”、“CourseComment”),
数据:{userName:userName},
键入:“获取”
}).完成(功能(数据){
$('#UserName').val(数据);
});
});
问题是视图只关心ModelState
中的内容。这让许多开发人员感到困惑,但仔细想想,这是合乎逻辑的
本质上,ModelState
当然是由Model
的值组成的,但也由ViewBag
、ViewData
和Request
中的值组成,它们覆盖了通过Model
设置的任何内容。要理解原因,请想象一个场景,其中用户正在编辑现有对象,但在其中一个值中出错,导致返回表单以更正其错误。如果使用了Model
中的值,则用户的编辑将完全撤消,并替换为对象上的原始值。但是,通过使用Request
中的值,ModelState
保留用户提交的值,只允许他们进行必要的更正
长话短说,您必须非常小心地命名请求参数、ViewBag
properties等,这与模型上的属性相同。在您的场景中,最简单的解决方案可能是将请求参数,userName
更改为其他内容
另外,值得一提的是,
ModelState
不区分大小写,因此UserName
与UserName
、UserName
、UserName
或UserName
一样适用于信息。最后我为它做了一个隐藏的字段。然后,当页面加载时,从javascript/ajax调用接收到值。
@Html.HiddenFor(model => model.UserName)
....
<script type="text/javascript">
$(function () {
var userName = '@User.Identity.Name.Split('\\')[1]';
$.ajax({
url: '@Url.Action("GetUserName", "CourseComment")',
data: { userName: userName },
type: 'get'
}).done(function (data) {
$('#UserName').val(data);
});
});