代码之家  ›  专栏  ›  技术社区  ›  C-Pfef

MVC 4 ModelState无效,因为它试图自动填充值而不接受新值

  •  1
  • C-Pfef  · 技术社区  · 9 年前

    我有一个评论区。在视图中只有一个注释编辑器框。

    @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>
    
    }
    

    该模型具有注释链接的过程、日期、注释文本和用户。其他值将在create-post方法中填充。

    [HttpPost]
    public ActionResult AddComment(CourseComment coursecomment, int courseID, String userName)
    {
        userName = userName.Split('\\')[1];
        coursecomment.CommentDate = System.DateTime.Now;
        coursecomment.CourseID = courseID;
        coursecomment.UserName = db.Users.FirstOrDefault(u => u.UserName == userName).UserID;
        if (ModelState.IsValid)
        {
            db.CourseComments.AddObject(coursecomment);
            db.SaveChanges();
        }
        return RedirectToAction("Details", "Course", new { courseID = courseID });
    }
    

    问题出现在这里。模型正在尝试使用 userName 的值的参数 courseComment.UserName 在我真正完成工作并设置之前。设置后 ModelState 不会改变。

    实例 domain\abc123 传递到post方法,并在 模型状态 对于 UserName .我做一些工作,改变 用户名 abc123 并找到具有所述名称的用户的链接ID(假设ID=1),然后将其插入 课程注释用户名 模型状态 仍然离开 域\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 });
    }
    

    到get方法。

    [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);
        });
    });
    
    1 回复  |  直到 9 年前
        1
  •  2
  •   Chris Pratt    9 年前

    问题是,所有观点都关心的是 ModelState 这对许多开发人员来说很困惑,但仔细想想,这是合乎逻辑的。

    基本上, 模型状态 由以下值组成 Model 当然,但也可以从 ViewBag , ViewData Request ,覆盖通过 模型 。要了解原因,请想象一个场景,其中用户正在编辑现有对象,但在其中一个值中出错,导致返回表单以更正错误。如果 模型 如果使用,用户的编辑将被完全撤消,替换为对象上的原始值。但是,通过使用 要求 , 模型状态 保留用户提交的值,只允许他们进行必要的更正。

    长话短说,您必须非常小心地命名请求参数, ViewBag(查看包) 属性等,与模型上的属性相同。在您的场景中,最简单的解决方案可能是更改请求参数, userName 到其他地方。

    而且,就其价值而言, 模型状态 不区分大小写,因此 UserName 用户名 , username , USERNAME UsErNaMe .