在控制器上传递所需属性的值,但仍然 ModelState.IsValid 为 false

本文关键字:ModelState false IsValid 控制器 属性 | 更新日期: 2023-09-27 18:36:39

我有一个部分视图,可以在我的主视图上为我的文章模块发表评论,以获取文章详细信息。注释模型有三个必填字段:ID(标识字段)、ArticleIdCommentText 。(我正在使用剃刀语法)

我试图在Create操作中在控制器处传递ArticleId

public ActionResult Create(ArticleComment articlecomment, string AID)
{
    articlecomment.ArticleId = AID;    //this is required
    if (User.Identity.IsAuthenticated)
    {
        articlecomment.UserId = WebSecurity.CurrentUserId.ToString();
    }
    else
    {
        articlecomment.UserId = Constants.Anonymus;
    }
    articlecomment.CommentDate = DateTime.Now;
    if (ModelState.IsValid)
    {
        db.ArticleComment.Add(articlecomment);
        int success = db.SaveChanges();
        if (success > 0)
        {
            return Content("<script language='javascript' type='text/javascript'>alert('Comment added successfully.');window.location.href='" + articlecomment.ArticleId + "';</script>");
        }
        else
        {
            return Content("<script language='javascript' type='text/javascript'>alert('Posting comment has failed, please try later.');window.location.href='" + articlecomment.ArticleId+ "';</script>");
        }
    }
    return PartialView(articlecomment);
}

ModelState.IsValid仍然返回错误。我使用了以下代码,发现ModelState ArticleId为空。

foreach (var modelStateValue in ViewData.ModelState.Values)
{
    foreach (var error in modelStateValue.Errors)
    {
        // Do something useful with these properties
        var errorMessage = error.ErrorMessage;
        var exception = error.Exception;
    }
}

我还想过使用 ViewBag 使用 Hidden 字段为ArticleId设置值,但没有找到任何工作代码。我尝试了以下操作:

@Html.HiddenFor(model => model.ArticleId, new { @value = ViewBag.Article })

 @Html.HiddenFor(model => model.ArticleId, (object)ViewBag.Article)

我发表评论的"部分视图"是:

@model Outliner.Models.ArticleComment
<script src="~/Scripts/jquery-1.8.2.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
@using (Html.BeginForm()) {
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

        <div class="editor-label">
           @* @Html.HiddenFor(model => model.ArticleId, new { @value = ViewBag.Article })
            @Html.HiddenFor(model => model.ArticleId, (object)ViewBag.Article)*@
            @Html.LabelFor(model => model.Comment) &nbsp;&nbsp;&nbsp;
            <span class="error">@Html.ValidationMessageFor(model => model.Comment)</span>  
        </div>
            @Html.TextAreaFor(model => model.Comment)        
            <input type="submit" value="Post" />        
}

这就是我在"ArticalDetail"视图(我的主要观点)上称呼这种部分视图的方式:

 @Html.Action("Create", "ArticleComment")

我之前在控制器上为视图传递了所需的字段值,但我遇到了部分视图的问题。我做错了什么,我怎样才能做到这一点?

尝试后编辑

当Satpal和Fals带领我走向一个方向时,我尝试了他们的建议,并尝试了以下内容:

TryUpdateModel(articlecomment);

还有

TryUpdateModel<ArticleComment>(articlecomment);

还有

TryValidateModel(articlecomment);

但我仍然收到相同的 ArticleId 验证错误,然后我检查了 Watch,我尝试的所有树方法都返回False

我还尝试了以下方法:

UpdateModel(articlecomment);

UpdateModel<ArticleComment>(articlecomment);

上述方法正在生成异常:

类型为"大纲.模型.文章注释"的模型不能 更新。

这是我的模型:

 [Table("ArticleComments")]
    public class ArticleComment
    {
        [Key]
        [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }
        [Required]
        public string ArticleId { get; set; }
        public string UserId { get; set; }
        [Required]
        [Display(Name = "Comment")]
        public string Comment { get; set; }
        [Required]
        [Display(Name = "Commented On")]
        public DateTime CommentDate { get; set; }
    }

我不明白,为什么我的模型没有更新... :(

在控制器上传递所需属性的值,但仍然 ModelState.IsValid 为 false

这是很晚的答案,但它应该有效。

ModelState.IsValid之前,添加以下内容

ModelState.Remove("ArticleId");

它将从验证中删除该字段。

您可以在检查ModelState.IsValid之前尝试TryUpdateModel(articlecomment)一次。但是我还没有测试过

在 ModelBind 之后更新任何必需字段后,必须调用另一个方法来更新验证。

您可以使用:

TryValidateModel(articlecomment);

TryUpdateModel<ArticleComment>(articlecomment);
对我来说

,您的@Html.Action(...)似乎编码它调用操作来创建部分视图,就像您所说的那样。 如果这样做,则不是调用分部视图的正确方法。 虽然操作返回分部视图并不少见,但根据我的经验,它通常是通过 AJAX 进行的,因此您可以在返回后将其插入 DOM 中。

可以使用以下方法呈现分部视图:

@{ 
    Html.RenderPartial("_myPartialView", 
                       new ArticleComment {ArticleId = model.Id}); 
}

这应该呈现您的分部视图,将您的模型传递给它,以便它可以正确呈现。 然后,当表单被 POST 到服务器时,它应该从表单数据创建模型。 不需要 AID 参数,因为它是ArticleComment模型的一部分。