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);
    });
});