【问题标题】:Trouble with passing data from ViewModel to View and PartialView将数据从 ViewModel 传递到 View 和 PartialView 出现问题
【发布时间】:2017-11-26 03:03:05
【问题描述】:

我正在构建一个非常简单的博客。对于我的博客,我需要两个模型:cmets 和消息。我知道要在您的视图中使用两个模型,您需要一个 ViewModel,但我遇到了很多困难。出于某种原因,我无法同时访问这两个模型,我的部分观点也是如此。现在我对 asp.net mvc 很陌生,知道这可能是一个愚蠢的错误,但我希望有人能告诉我我做错了什么,最重要的是为什么!

这是我的模型

namespace Portfolio.Models
{
    public class Messages
    {
        public int MessagesId { get; set; }
        [Required]
        public string Title { get; set; }
        [Required]
        public string Body { get; set; }
        public DateTime WhenCreated { get; set; }

        public Messages()
        {
            WhenCreated = DateTime.Now;
        }
    }
}

namespace Portfolio.Models
{
    public class Comments
    {
        public int CommentsId { get; set; }
        public string Comments_body { get; set; }
        public Messages MessagesId { get; set; }
        public DateTime WhenCreated { get; set; }

        public Comments()
        {
            WhenCreated = DateTime.Now;
        }
    }
}

这是我的 ViewModel

namespace Portfolio.ViewModels
{
    public class MessageViewModel
    {
        public IEnumerable<Messages> Messages { get; set; }
        public IEnumerable<Comments> Comments { get; set; }
    }
}

我的控制器

    namespace Portfolio.Controllers
{
    public class MessagesController : Controller
    {
        private ApplicationDbContext _context;

        public MessagesController()
        {
            _context = new ApplicationDbContext();
        }

        protected override void Dispose(bool disposing)
        {
            _context.Dispose();
        }
        public ActionResult Blog()
        {
            var messages = _context.messages.ToList();

            return View(_context.messages.OrderByDescending(Messages => 
            Messages.WhenCreated));
        }

        public ActionResult Comment()
        {
            var comment = _context.comments.ToList();

            return View(_context.comments.OrderByDescending(Comments => 
            Comments.WhenCreated));
        }
        public ActionResult Post()
        {
            return View();
        }


        //This binds the objects from the database to the values from the 
        view

        [ValidateInput(false)]
        [HttpPost]
        public ActionResult Create(FormCollection formValues)
        {
            try
            {
                Messages message = new Messages();
                message.Title = formValues["Title"];
                message.Body = formValues["editor"];

                Comments comment = new Comments();
                comment.Comments_body = formValues["editor" + 
                message.MessagesId];

                _context.comments.Add(comment);
                _context.SaveChanges();
                _context.messages.Add(message);
                _context.SaveChanges();

           }
            catch
            {
                return View();
            }
            return RedirectToAction("Blog");
       }
    }
}

这是我的观点

@model IEnumerable<Portfolio.ViewModels.MessageViewModel>

@{
    ViewBag.Title = "Blog";
    Layout = "~/Views/Shared/_Layout.cshtml";
 }
<link rel="stylesheet" type="text/css" href="~/Content/css/Blog.css" />
<script src="~/Scripts/ckeditor/ckeditor.js"></script>

<div class="jumbotron opacity_container">
    <div class="row">
        <div class="col-md-12">
            <h2>Latest Posts</h2>
            <div class="row">
                <div class="col-md-12">
                    @foreach (var messages in Model)
                    {
                        <div class="jumbotron opacity_container">
                            <div class="col-md-12">
                                <div class="panel panel-primary">
                                    <div class="panel-heading">
                                        @*Gets the title of the blog post*@
                                        <h2 class="panel-title">
                                        @messages.Title
                                        </h2>@messages.WhenCreated
                                   </div>
@*Gets the body of the blog post and decodes the html of the ckeditor*@

                                <div class="panel-body">
                 @Html.Raw(System.Web.HttpUtility.HtmlDecode(messages.Body))
                                </div>
                            </div>
                        </div>
 @*this button gets the id from the database of the 
 Message table this helps to prevent that all the comments from all blogs 
 gets shown and thus shows only the comments that belong to the blog in 
 question*@

                    <button class="btn btn primary"id="@messages.MessagesId"
                    onclick="ShowComments(this.id)">
                    Show Comments
                    </button>

@*this is the container where al the comments are placed in and where you 
can post comments. The comments are placed in the Comment partial view*@
                        <div class="hidden" id="Comm@(messages.MessagesId)">
                            @Html.Partial("_Comment", Model)

@*this button gets the id from the database of the Message table this helps 
to prevent that all the comments from all blogs gets hidden and thus
hides only the comments that belong to the blog in question*@
                        <button class="btn btn-primary" 
                        id="@messages.MessagesId" 
                        onclick="HideComments(this.id)">Hide Comments
                        </button>
                    </div>
                </div>
                }
            </div>
        </div>
    </div>
</div>

这是我的部分观点

@{
   ViewBag.Title = "Home Page";
}
<link rel="stylesheet" type="text/css" href="~/Content/css/Blog.css" />

<div class="row" id="CommentContainer">
    <div class="col-md-12">
        <h3>Post Comment</h3>
 @*The form to post comments*@
        @using (Html.BeginForm("Create", "Messages"))
            {
            <div class="form-group">
                <label>Comment</label>
                @Html.TextArea("editor1", htmlAttributes: new { name = 
               "editor1", id = "editor", rows = "10", cols = "180" })
            </div>
                <button type="submit" class="btn btn-primary" 
              id="PostButton">Post Comment</button>
            }

 @*CKEdito script*@
        <script>
             CKEDITOR.replace('editor1');
        </script>


        <div class="row">
            <div class="col-md-10">
@*Places al the comments and decodes the html from the ckeditor*@
                @foreach(var comments in Model)
                {
                    <div class="well" id="CommentBox">

@Html.Raw(System.Web.HttpUtility.HtmlDecode(comments.Comments_body))
                    </div>
                }
            </div>
        </div>
    </div>
</div>

此 PartialView 显示 cmets,而 View 显示博客消息。 所以我需要将数据从我的消息模型发送到我的视图,并且我需要在我的局部视图中从我的 cmets 模型发送和检索数据。

感谢您的帮助!

【问题讨论】:

  • 您现在是否收到任何类型的错误消息?如果可以,可以分享一下吗?
  • 这是我收到的错误消息 MessageViewModel'不包含'Title'的定义,并且找不到接受'MessageViewModel'类型的第一个参数的扩展方法'Title'(您是否缺少使用指令还是程序集引用?)
  • 您已将视图的模型属性设置为集合 ViewModel 类,但您正在向视图发送 cmets 或消息集合

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


【解决方案1】:

为了在您的视图中使用您的 ViewModel,您需要将它从您的控制器传递给您的视图。您当前正在传递一组消息:

public ActionResult Blog()
{
    var messages = _context.messages.ToList();

    // Your view is expecting a parameter of type MessageViewModel,
    // but you're passing it an object of type List<Messages>
    return View(_context.messages.OrderByDescending(Messages => Messages.WhenCreated));
}

如果您想使用 ViewModel,请尝试以下操作:

public ActionResult Blog()
{
    // Create a MessageViewModel and assign its properties...
    var viewModel = new MessageViewModel()
        {
           Messages = _context.messages.OrderByDescending(m => m.WhenCreated),
           Comments =  _context.comments
        };

    // Pass the MessageViewModel to your view.
    return View(viewModel);
}

您还需要更新您的视图:

@model Portfolio.ViewModels.MessageViewModel
...
@foreach (var messages in Model.Messages)
...
@Html.Partial("_Comment", Model.Comments)

你会想让你的局部视图接受一个参数 IEnumerable&lt;Comments&gt; 的型号:

@model IEnumerable<Portfolio.Models.Comments>

请注意,此解决方案当前正在从 _context 获取 所有 消息和 所有 cmets 并将它们传递给视图。您可能想要过滤它们(仅传递附加到特定消息的 cmets 等)。

【讨论】:

  • 我已经采纳了您的建议,但仍然遇到同样的错误。我只更改了控制器而不是视图,所以也许我在视图中调用它是错误的?
  • 我刚刚更新了答案,包括对视图和部分视图的一些更改。
  • thnx 将立即尝试。我对 c# 和 asp.net 都很陌生,非常感谢您的帮助
  • 所以当我将鼠标悬停在 @messages.WhenCreated 上时,我已经尝试过它并在 Visual Studio 中显示:DateTime Portfolio.Models.Messages.WhenCreated{get; set;} 所以我认为它是正确传递的,但是当我编译时,我现在得到错误 IEnumerable' does not contain a definition for 'Messages' and no extension method 'Messages'接受'IEnumerable'类型的第一个参数' 可以找到(您是否缺少 using 指令或程序集引用?)
  • 错误指向这部分:@foreach (var messages in Model.Messages) 我觉得很奇怪,因为在 Visual Studio 中它显示它是正确传递的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-15
  • 2022-01-21
  • 1970-01-01
  • 1970-01-01
  • 2020-02-17
  • 2014-01-30
相关资源
最近更新 更多