在Controller传递所需属性的值,但ModelState.IsValid仍为false

时间:2013-10-23 16:48:11

标签: c# asp.net-mvc-4 razor

我有一个部分视图,可以在文章详细信息的主视图上发布我的文章模块的评论。评论模型有三个必填字段ID(标识字段),ArticleIdCommentText。 (我正在使用Razor语法)

我尝试在ArticleId操作中的控制器上传递Create

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仍然返回false。我使用了以下代码,发现ModelStateArticleId视为空。

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

我还想过使用ArticleId使用隐藏字段为ViewBag设置值,但找不到任何正常工作的代码。我试过以下:

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

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

发表评论的我的'ParticalView'是:

@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")

我之前在View的控制器上传递了必需的字段值,但我面临PartialView的问题。我做错了什么,我该怎么做才能做到这一点?

编辑后尝试

当Satpal和Fals带领我走向一个方向时,我尝试了他们的建议,并试着跟随:

TryUpdateModel(articlecomment);

以及

TryUpdateModel<ArticleComment>(articlecomment);

以及

TryValidateModel(articlecomment);

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

我也尝试过:

UpdateModel(articlecomment);

UpdateModel<ArticleComment>(articlecomment);

上述方法正在生成异常:

  

“Outliner.Models.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; }

    }

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

4 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

在模型绑定后更新任何必填字段后,必须调用另一个方法来更新验证。

您可以使用:

TryValidateModel(articlecomment);

TryUpdateModel<ArticleComment>(articlecomment);

答案 2 :(得分:1)

答案很晚,但应该有效。

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

ModelState.Remove("ArticleId");

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

答案 3 :(得分:0)

对我来说,似乎你的@Html.Action(...)代码调用了创建局部视图的动作,就像你说的那样。如果您这样做,则不是调用局部视图的正确方法。虽然一个动作返回局部视图的情况并不少见,但根据我的经验,通常是通过AJAX,所以你可以在它返回后将它插入DOM。

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

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

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