1个视图中的2个模型MVC4

时间:2013-01-02 12:30:39

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

我有两个模型,如下所示:

一:

 [Validator(typeof(BlogPostValidator))]
    public partial class BlogPostModel : BaseNopEntityModel
    {
        public BlogPostModel()
        {
            Tags = new List<string>();
            Comments = new List<BlogCommentModel>();
            AddNewComment = new AddBlogCommentModel();
        }

        public string SeName { get; set; }

        public string Title { get; set; }

        public string Body { get; set; }

        public bool AllowComments { get; set; }

        public int NumberOfComments { get; set; }

        public DateTime CreatedOn { get; set; }

        public IList<string> Tags { get; set; }

        public IList<BlogCommentModel> Comments { get; set; }
        public AddBlogCommentModel AddNewComment { get; set; }

        public BlogCommentModel blogcommentmodel { get; set; }
    }

2:

 public partial class BlogCommentModel : BaseNopEntityModel
    {
        public int CustomerId { get; set; }

        public string CustomerName { get; set; }

        public string CustomerAvatarUrl { get; set; }

        public string CommentText { get; set; }

        public DateTime CreatedOn { get; set; }

        public bool AllowViewingProfiles { get; set; }

        public int CommentParentID { get; set; }

        public IList<BlogComment> ChildCommentList { get; set; }//netra
    }

我想利用 BlogCommentModel 中的 ChildCommentList 来显示嵌套的评论。

我的观点:

@model BlogPostModel
@using Nop.Web.Models.Blogs;
 @if (Model.AllowComments)
        {
            <div class="clear">
            </div>
            <fieldset class="new-comment" id="addcomment">
                <legend class="title">@T("Blog.Comments.LeaveYourComment")</legend>
                @using (Html.BeginForm())
                {
                    <div>
                        <div class="message-error">@Html.ValidationSummary(true)</div>
                        @{
                    string result = TempData["nop.blog.addcomment.result"] as string;
                        }
                        @if (!String.IsNullOrEmpty(result))
                        {
                            <div class="result">@result</div>
                        }
                        <div class="forms-box">
                            <div class="inputs">
                                @Html.LabelFor(model => model.AddNewComment.CommentText)
                                <div class="input-box">
                                    @Html.TextAreaFor(model => model.AddNewComment.CommentText, new { @class = "comment-text" })
                                </div>
                                @Html.ValidationMessageFor(model => model.AddNewComment.CommentText)
                            </div>
                            @if (Model.AddNewComment.DisplayCaptcha)
                            {
                                <div class="captcha-box">
                                    @Html.Raw(Html.GenerateCaptcha())
                                </div>
                                <div class="clear">
                                </div>
                            }
                        </div>
                        <div class="clear">
                        </div>
                        <div class="buttons">
                            <input type="submit" name="add-comment" class="button-1 blog-post-add-comment-button" value="@T("Blog.Comments.SubmitButton")" />
                        </div>
                    </div>
                }
            </fieldset>
                if (Model.Comments.Count > 0)
                {
            <div class="clear">
            </div>
            <div class="comment-list">
                <div class="title">
                    @T("Blog.Comments")
                </div>
                <div class="clear">
                </div>
                @foreach (var comment in Model.Comments)
                {
                    <div class="blog-comment">
                        <div class="comment-info">
                            <div class="user-info">
                                @if (comment.AllowViewingProfiles)
                                {
                                    <a href="@Url.RouteUrl("CustomerProfile", new { id = comment.CustomerId })" class="username">@(comment.CustomerName)</a>
                                }
                                else
                                {
                                    <span class="username">@(comment.CustomerName)</span>
                                }
                                <div class="avatar">
                                    @if (!String.IsNullOrEmpty(comment.CustomerAvatarUrl))
                                    {
                                        <img src="@(comment.CustomerAvatarUrl)" class="avatar-img" title="avatar" alt="avatar" />
                                    }
                                </div>
                            </div>
                        </div>
                        <div class="comment-content">
                            <div class="comment-time">
                                @T("Blog.Comments.CreatedOn"): <span class="stat-value">@comment.CreatedOn.ToString("g")</span>
                            </div>
                            <div class="comment-body">
                                @Html.Raw(Nop.Core.Html.HtmlHelper.FormatText(comment.CommentText, false, true, false, false, false, false))
                            </div>
                        </div>
                        @Html.Widget("blogpost_page_inside_comment")
                    </div>
                    <div class="clear">
                    </div>
                    <div>
                     @foreach(var childcomments in Model.blogcommentmodel.ChildCommentList)
                     {
                      @Html.Raw(Nop.Core.Html.HtmlHelper.FormatText(childcomments.CommentText, false, true, false, false, false, false))
                     }
                    </div>
                }
                <div class="buttons">
                    <input type="submit" id="replyto" name="reply-comment" class="button-1 blog-post-add-comment-button" value="@T("Blog.Comments.ReplyButton")" />
                </div>
            </div>
                }
        }

发生错误:

@foreach(var childcomments in Model.blogcommentmodel.ChildCommentList)
                         {
                          @Html.Raw(Nop.Core.Html.HtmlHelper.FormatText(childcomments.CommentText, false, true, false, false, false, false))
                         }
                        </div>
                    }

NullReferenceException未被usercode处理 - {“对象引用未设置为对象的实例。”}

我的ActionResult控制器代码:

public ActionResult BlogPost(int blogPostId)
        {
            if (!_blogSettings.Enabled)
                return RedirectToRoute("HomePage");

            var blogPost = _blogService.GetBlogPostById(blogPostId);
            if (blogPost == null ||
                (blogPost.StartDateUtc.HasValue && blogPost.StartDateUtc.Value >= DateTime.UtcNow) ||
                (blogPost.EndDateUtc.HasValue && blogPost.EndDateUtc.Value <= DateTime.UtcNow))
                return RedirectToRoute("HomePage");

            var model = new BlogPostModel();
            **PrepareBlogPostModel(model, blogPost, true);**

            return View(model);
        }

在上面ActionResult中调用的方法:

 [NonAction]
        protected void PrepareBlogPostModel(BlogPostModel model, BlogPost blogPost, bool prepareComments)
        {
            if (blogPost == null)
                throw new ArgumentNullException("blogPost");

            if (model == null)
                throw new ArgumentNullException("model");

            model.Id = blogPost.Id;
            model.SeName = blogPost.GetSeName();
            model.Title = blogPost.Title;
            model.Body = blogPost.Body;
            model.AllowComments = blogPost.AllowComments;
            model.CreatedOn = _dateTimeHelper.ConvertToUserTime(blogPost.CreatedOnUtc, DateTimeKind.Utc);
            model.Tags = blogPost.ParseTags().ToList();
            model.NumberOfComments = blogPost.ApprovedCommentCount;
            model.AddNewComment.DisplayCaptcha = _captchaSettings.Enabled && _captchaSettings.ShowOnBlogCommentPage;
            if (prepareComments)
            {
               // var blogchildcomment = _blogService.GetAllChildComments();
                var blogComments = blogPost.BlogComments.Where(pr => pr.IsApproved).OrderBy(pr => pr.CreatedOnUtc);
                foreach (var bc in blogComments)
                {
                    var commentModel = new BlogCommentModel()
                    {
                        Id = bc.Id,
                        CustomerId = bc.CustomerId,
                        CustomerName = bc.Customer.FormatUserName(),
                        CommentText = bc.CommentText,
                        CreatedOn = _dateTimeHelper.ConvertToUserTime(bc.CreatedOnUtc, DateTimeKind.Utc),
                        AllowViewingProfiles = _customerSettings.AllowViewingProfiles && bc.Customer != null && !bc.Customer.IsGuest(),
                        CommentParentID = bc.CommentParentID,//Netra
                    };
                    //Netra
                    var comments = _blogService.GetBlogComments(bc.CommentParentID);
                    if (comments != null)
                    {
                        commentModel.ChildCommentList = new List<BlogComment>(); 
                        foreach (var cmnt in comments)
                        {
                            commentModel.ChildCommentList.Add(cmnt);
                        }
                    }

                    if (_customerSettings.AllowCustomersToUploadAvatars)
                    {
                        var customer = bc.Customer;
                        string avatarUrl = _pictureService.GetPictureUrl(customer.GetAttribute<int>(SystemCustomerAttributeNames.AvatarPictureId), _mediaSettings.AvatarPictureSize, false);
                        if (String.IsNullOrEmpty(avatarUrl) && _customerSettings.DefaultAvatarEnabled)
                            avatarUrl = _pictureService.GetDefaultPictureUrl(_mediaSettings.AvatarPictureSize, PictureType.Avatar);
                        commentModel.CustomerAvatarUrl = avatarUrl;
                    }
                    model.Comments.Add(commentModel);
                }
            }
        } 

BlogComment是描述属性的类。

 public partial class BlogComment : CustomerContent
    {
        /// <summary>
        /// Gets or sets the comment text
        /// </summary>
        public virtual string CommentText { get; set; }

        /// <summary>
        /// Gets or sets the blog post identifier
        /// </summary>
        public virtual int BlogPostId { get; set; }

        /// <summary>
        /// Gets or sets the blog post
        /// </summary>
        public virtual BlogPost BlogPost { get; set; }

        public virtual int CommentParentID { get; set; } //netra
    }

3 个答案:

答案 0 :(得分:0)

所以你在某个地方有一个null - 你需要找出什么是null并使它成为它所以它不是null;或者将Razor代码更改为:

@if(Model.blogcommentmodel != null && Model.blogcommentmodel.ChildCommentList != null)
{
  @* original @foreach statement here *@
}

答案 1 :(得分:0)

我的第一个猜测是你需要为你的模型创建一个默认构造函数。在构造函数中,设置ChildCommentList = new List<BlogComment>();

看起来你没有在你的控制器中设置它,你设置模型的方式会导致ChildCommentList仍然为空。使用该默认构造函数,如果您错过了在某处设置代码,则不必担心代码会破坏。

要回答wnetra的评论,构造函数位于BlogcommentModel类上。所以你需要这样的东西:

public class BlogcommentModel {
    /* All of the property declarations */
    public IList<BlogComment> ChildCommentList { get; set; }

    /* Constructor for the BlogcommentModel class */
    public BlogcommentModel() {
        ChildcommentList = new List<BlogComment>();
    }
}

任何引用对象都应该始终在默认构造函数中实例化,以确保在尝试在代码中引用它们时它们不会为null。

另见Andras&#39;回答在尝试引用代码中的引用对象时始终执行!= null

答案 2 :(得分:0)

我已从BlogCommenmodel中删除了以下代码:

//public int CommentParentID { get; set; }

    //public IList<BlogComment> ChildCommentList { get; set; }//netra

    //public BlogCommentModel()
    //{
    //    ChildCommentList = new List<BlogComment>();
    //}

并在BlogPostModel中引入

 [Validator(typeof(BlogPostValidator))]
public partial class BlogPostModel : BaseNopEntityModel
{
    public BlogPostModel()
    {
        Tags = new List<string>();
        Comments = new List<BlogCommentModel>();
        AddNewComment = new AddBlogCommentModel();
        ChildCommentList = new List<BlogComment>();
    }

    public string SeName { get; set; }

    public string Title { get; set; }

    public string Body { get; set; }

    public bool AllowComments { get; set; }

    public int NumberOfComments { get; set; }

    public DateTime CreatedOn { get; set; }

    public IList<string> Tags { get; set; }

    public IList<BlogCommentModel> Comments { get; set; }
    public AddBlogCommentModel AddNewComment { get; set; }


    //Netra
    public int CommentParentID { get; set; }

    public IList<BlogComment> ChildCommentList { get; set; }//netra

   // public BlogCommentModel blogcommentmodel { get; set; }
}

在视图中:

<div>
                            @if (Model.ChildCommentList != null)
                            {
                                foreach (var childcomments in Model.ChildCommentList)
                                {
                                    @Html.Raw(Nop.Core.Html.HtmlHelper.FormatText(childcomments.CommentText, false, true, false, false, false, false))
                                }
                            }
                        </div>