表格不保存数据到模型

时间:2014-05-18 08:45:48

标签: c# entity-framework asp.net-mvc-4

我正在使用MVC来构建博客。我想要的是将帖子评论保存到数据库中的相应位置,但它不起作用。

我的帖子模型如下:

public class Post
{
    [Key]
    public int PostId { get; set; }
    public string Title { get; set; }
    public DateTime CreatedDate{get;set;}
    public DateTime UpdateDate { get; set; }
    public string Body { get; set; }
    public ICollection<Comment> Comments { get; set;}
    public ICollection<Tag> Tags { get; set; } 

}

我的评论模型如下:

   public class Comment
    {

        [Key]
        public int CommentId { get; set; }
        public int PostId { get; set; }
        [ForeignKey("PostId")]
        public virtual Post Post{get; set;}
        public string CommentCreateDate { get; set; }
        public string CommentUpdateDate { get; set; }
        public string CommeterName { get; set; }
        public string EmailAddress { get; set; }
        public string CommentText { get; set; }
        public bool Approved { get; set; }

    }

我有以下行动方法:

[HttpGet]
    public ActionResult CreateComment()
    {
        return View();
    }

    [HttpPost]
    [ValidateInput(false)]
    public ActionResult CreateComment(int id, string name, string email, string txt, bool aproved = false)
    {

        Post post = GetPost(id);
        Comment comment = new Comment();
        comment.Post = post;
        comment.CommentCreateDate = DateTime.Now.ToString();
        comment.CommeterName = name;
        comment.EmailAddress = email;
        comment.CommentText = txt;
        comment.Approved = aproved;
        db.Comments.Add(comment);
        db.SaveChanges();

        m_commentList.Add(comment);



        return RedirectToAction("CreateComment", new { id = id });

    }

在我看来,我正在尝试这个:

@model Blog.Models.Comment

@{
    ViewBag.Title = "CreateComment";
}

<h2>Create a Comment</h2>


    @using (Html.BeginForm())
    {
        <fieldset>

            <legend>Enter Comment</legend>

            <div class="editor-label">
                @Html.LabelFor(model => model.CommeterName)
            </div>
            <div class="editor-field">
                @Html.TextBoxFor(model => model.CommeterName)
            </div>
            <div class="editor-label">
                @Html.LabelFor(model => model.EmailAddress)
            </div>
            <div class="editor-field">
                @Html.TextBoxFor(model => model.EmailAddress)
            </div>
            <div class="editor-label">
                @Html.LabelFor(model => model.CommentText)
            </div>
            <div class="editor-field">
                @Html.TextAreaFor(model => model.CommentText)
            </div>
            <p>
                <input type="submit" value="Create comment" />
            </p>

        </fieldset>

    }

我没有例外,但没有保存表单中的数据。仅限操作结果中设置的数据,即CommentCreateDate和Approved。我不确定我做错了什么。

我尝试了第二个选项,即在BeginForm()中包含注释的id,如下所示:

 @using (Html.BeginForm(new {id = Model.CommentId}))
{
    <fieldset>

        <legend>Enter Comment</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.CommeterName)
        </div>
        <div class="editor-field">
            @Html.TextBoxFor(model => model.CommeterName)
        </div>
        <div class="editor-label">
            @Html.LabelFor(model => model.EmailAddress)
        </div>
        <div class="editor-field">
            @Html.TextBoxFor(model => model.EmailAddress)
        </div>
        <div class="editor-label">
            @Html.LabelFor(model => model.CommentText)
        </div>
        <div class="editor-field">
            @Html.TextAreaFor(model => model.CommentText)
        </div>
        <p>
            <input type="submit" value="Create comment" />
        </p>

    </fieldset>

}

即使我使用new关键字,这也会给我一个空引用异常:

System.NullReferenceException: Object reference not set to an instance of an object.

为什么会这样?有人可以帮忙吗?

谢谢

1 个答案:

答案 0 :(得分:2)

您的行动签名应为:

public ActionResult CreateComment(Comment model)

为表单字段生成的名称将绑定回相同模型类的属性。例如,框架无法知道CommenterName属性应该与操作的name参数匹配。

你的第二个例子没什么意义 - 你试图写出ID,但你从未设置过。实际上,您甚至没有将Comment传递给带有表单的视图,这就是您获得NullReferenceException的原因:

[HttpGet]
public ActionResult CreateComment()
{
    return View();
}

此外,您应该注意您向模型和操作公开的字段。例如,用户可以通过浏览器的开发控制台添加以下标记,轻松强制批准他们的评论:

<input type="hidden" name="approved" value="true" />

用户可以设置模型属性中的任何内容或操作的参数

一个更好的选择是为表单使用专用的模型类:

public class CreateCommentViewModel
{
    public string Name { get; set; }
    public string Email { get; set; }
    public string Text { get; set; }
}

然后使用以下内容将此映射到您的Comment {/ p>

[HttpPost]
public ActionResult CreateComment(CommentViewModel model)
{
    var comment = new Comment();
    comment.CommenterName = model.Name;
    // etc...
}

这可以防止用户设置ApprovedCreatedDate之类的内容。