C#模型绑定到自定义类不起作用

时间:2017-04-06 13:49:13

标签: c# asp.net-mvc

我很难让MVC绑定到我创建的模型。我过去成功地完成了这几次。因此,我不确定为什么它不适用于这个项目。

例如,我有以下视图:

    @model StoryWall.ViewModels.ViewPostViewModel
@{
    ViewBag.Title = "View Post";
}

<article class="story">
    <header>
        <h1>@Model.story.Title</h1>
        <spann class="text-muted">@Model.story.Store.StoreName</span>
            <h2>Posted by @Model.story.PosterName</h2>
</header>

    if(@Model.story.StoryImage != null) {
    <div class="storyImageWrapper">
        <img src="~/img/@Model.story.StoryImage" />
    </div>

    <p>@Model.story.StoryBody</p>
    }
</article>

<div class="commentsSection">
    <h2>Comments</h2>
    <h3>Add a Comment</h3>
    <form method="post" class="form-horizontal" name="CommentForm" action="/View/AddComment">
        @Html.AntiForgeryToken()
        <input type="hidden" name="newComment.StoryID" value="@Model.story.StoryID" />
        <div class="form-group"><label class="control-label col-sm-2">Name </label><div class="col-sm-10">@Html.TextBoxFor(@m => m.newComment.CommenterName, new { @class = "form-control", @required = true, @ng_model = "CommenterName"})  <span class="text-warning" ng-show="CommentForm.newComment.CommenterName.$dirty && CommentForm.newComment.CommenterName.$invalid"> Required </span> <span class="text-warning"> @Html.ValidationMessageFor(@m => m.newComment.CommenterName) </span></div> </div>
        <div class="form-group"><label class="control-label col-sm-2">Email </label><div class="col-sm-10">@Html.TextBoxFor(@m => m.newComment.CommenterEmail, new { @class = "form-control", @required = true, @ng_model = "CommenterEmail" })  <span class="text-warning" ng-show="CommentForm.newComment.CommenterEmail.$dirty && CommentForm.newComment.CommenterEmail.$invalid"> Required </span> <span class="text-warning"> @Html.ValidationMessageFor(@m => m.newComment.CommenterEmail) </span></div> </div>
        <div class="form-group"><label class="control-label col-sm-2">Message </label><div class="col-sm-10">@Html.TextAreaFor(@m => m.newComment.CommentBody, new { @class = "form-control", @required = true, @ng_model = "CommentBody" })  <span class="text-warning" ng-show="CommentForm.newComment.CommentBody.$dirty && CommentForm.newComment.CommentBody.$invalid"> Required </span> <span class="text-warning"> @Html.ValidationMessageFor(@m => m.newComment.CommentBody) </span></div> </div>
        <button type="submit" ng-disabled="CommentForm.$invalid">Submit</button>
    </form>
    <h3>Current Comments</h3>
    @foreach(var comment in @Model.story.Comments) {
        <blockquote>@comment.CommentBody</blockquote>
   <span>Poster: @comment.CommenterName on @comment.DatePosted.ToString("MM-dd-yyyy")</span>

    }

</div>

即使我专门为输入框使用Html.TextBoxFor(),绑定仍然没有按预期工作。

这是我的控制器。 &#34;评价&#34;在第二个Action方法中没有正确绑定;它的属性为null。

   public class ViewController : Controller
{

    StoryModel dbContext = new StoryModel();

    public ActionResult ViewPost(Int32 postID)
    {
        ViewPostViewModel vm = new ViewPostViewModel();
        vm.story = dbContext.Stories.FirstOrDefault(s => s.StoryID == postID);
        return View(vm);
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult AddComment(Comment comment)
    {

        if (ModelState.IsValid)
        {
            dbContext.Comments.Add(comment);
            dbContext.SaveChanges();
            return RedirectToAction("ViewPost", new { storyID = comment.StoryID});
        }
        else
        {
            ViewPostViewModel vm = new ViewPostViewModel();
            vm.story = dbContext.Stories.FirstOrDefault(s => s.StoryID == comment.StoryID);
            vm.newComment = comment;
            return View("ViewPost", vm);
        }
    }
}

我知道这不是第一次提出类似的问题,但我找不到解决问题的解决方案。此外,如上所述,这是我过去成功完成的事情。

唯一的&#34;新&#34;这个场景中的元素对我来说是Angular.js。这是我第一次使用该框架。它能以某种方式干扰绑定吗?

如果有帮助,评论模型:

public partial class Comment
{
    public int CommentID { get; set; }

    public int? StoryID { get; set; }

    public int UserID { get; set; }

    [Required]
    [StringLength(75)]
    public string CommenterName { get; set; }

    [Required]
    [StringLength(75)]
    public string CommenterEmail { get; set; }

    [Required]
    public DateTime DatePosted { get; set; }

    [Required]
    public string CommentBody { get; set; }


    public virtual Story Story { get; set; }

    public virtual User User { get; set; }
}

和ViewPostViewModel

    public class ViewPostViewModel
{

    public Story story { get; set; }
    public Comment newComment  { get; set; }
}

}

非常感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

一个答案是使用 @ Html.EditorFor()

@Html.EditorFor(m => m.newComment)

然后在放置视图的文件夹上创建一个名为EditorTemplates的新文件夹,其视图的名称与对象类型完全相同。在这种情况下, Comment.cshtml

视图可能是这样的 - &gt;

@model StoryWall.ViewModels.Comment

@Html.TextBoxFor(m => m.CommenterName)
@Html.TextBoxFor(m => m.CommenterEmail)
@Html.TextAreaFor(m => m.CommentBody)

这种方法是我通常用于处理列表的方法(在调查或测试中有用),但它也适用于单个项目。

另一种方法可能是将所有内容添加到viewmodel,因为viewmodel不需要是业务对象或数据库模型的一对一映射。 :)

编辑:忘记添加。我认为使用这种方法接收帖子的方法必须接收整个ViewModel而不仅仅是注释。 - &GT;

public ActionResult AddComment(ViewPostViewModel vm)