【问题标题】:Unable to display all fields of ViewModel无法显示 ViewModel 的所有字段
【发布时间】:2018-08-16 16:43:57
【问题描述】:

我想要完成的是让视图显示我的所有字段。目前,我已经设置了一个 ViewModel 并将其传递给我的 View。 ViewModel如下:

NewReportViewModel.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using BugTracker.Models;

namespace BugTracker.ViewModels
{
    public class NewReportViewModel
    {
        public IEnumerable<RequestType> RequestType { get; set; }
        public IEnumerable<Urgency> Urgency { get; set; }
        public Report Report { get; set; }
    }
}

RequestType、Urgency、Report的模型如下:

RequestType.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace BugTracker.Models
{
    public class RequestType
    {
        public byte ID { get; set; }
        public string RequestBC { get; set; }
    }
}

Urgency.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace BugTracker.Models
{
    public class Urgency
    {
        public byte ID { get; set; }
        public string UrgencyLevel { get; set; }
    }
}

Report.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;

namespace BugTracker.Models
{
    public class Report
    {
        public int ID { get; set; }
        public String Name { get; set; }
        public String Description { get; set; }
        public RequestType RequestType { get; set; }
        public Urgency Urgency { get; set; }
        public String URL { get; set; }
        public DateTime DateSubmitted { get; set; }
    }
}

据我了解,如果我想在一个视图中获取 RequestType、Urgency 和 Report 全部内容,我需要将其作为 ViewModel 传递。

因此,我在ReportController.cs文件中做了如下操作:

    public ActionResult Report()
    {
        var requestType = _context.RequestType.ToList();
        var urgency = _context.Urgency.ToList();
        var viewModel = new NewReportViewModel
        {
            RequestType = requestType,
            Urgency = urgency
        };
        return View(viewModel);
    }

话虽如此,我似乎无法弄清楚如何正确显示所有内容!这是我对报告的看法:

Report.cshtml

@model BugTracker.ViewModels.NewReportViewModel
@{
    ViewBag.Title = "Report";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Bugs and Changes</h2>
<table class="table table-bordered table-hover">
    <thread>
        <tr>
            <th>Issue Name</th>
            <th>Request Type</th>
            <th>Priority</th>
            <th>Bug Description</th>
            <th>URL</th>
            <th>Date Submitted</th>
        </tr>
    </thread>
    <tbody>
        @foreach (var report in Model)
        {
        <tr>
            <td>@Html.ActionLink(report.Name, "Edit", "Customers", new { id = report.ID }, null)</td>
            <td>@report.RequestType.RequestBC</td>
            <td>@report.Urgency.UrgencyLevel</td>
            <td>@report.Description</td>
            <td>@report.URL</td>
            <td>@report.DateSubmitted.ToShortDateString()</td>
        </tr>
        }
    </tbody>
</table>

每当我尝试运行它时,它都会抱怨IEnumerable。根据我的研究,看起来@foreach 行需要所有数据为IEnumerable。但是,显然 Report.cs 模型不是 IEnumerable(我认为我也做不到)。

但是,我的 Urgency.cs 和 RequestType.cs 模型需要为 IEnumerable,因为我将它们用作创建新表单的视图中的下拉选项。这引出了我的问题:

如何查看包含 IEnumerable 字段和非 IEnumerable 字段的 ViewModel 并让它显示所有字段?我需要改变什么?

【问题讨论】:

  • 您没有在视图模型中通过“报告”

标签: asp.net asp.net-mvc asp.net-mvc-4


【解决方案1】:

感谢大家的帮助!我查看了几个资源,最后通过学习 Mosh 的 Udemy MVC 课程得到了答案。首先,我的 NewReportViewModel.cs、Urgency.cs 或 RequestType.cs 视图模型和模型没有任何问题。但是, 之后的一切都出现了问题。首先,让我们从 Report.cs 开始...

这里的问题是我有一个 RequestType 对象,还有一个 Urgency 对象。我没有的是一个 ID - 这很重要,因为 RequestType 和 Urgency 本身就是表,并且可以通过它们的外键 RequestTypeId 和 UrgencyID 从报告表中访问。因此,它应该看起来像这样:

Report.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;

namespace BugTracker.Models
{
    public class Report
    {
        public int ID { get; set; }
        public String Name { get; set; }
        public String Description { get; set; }

        public RequestType RequestType { get; set; }
        public byte RequestTypeId {get; set;}

        public Urgency Urgency { get; set; }
        public byte UrgencyId {get; set; }

        public String URL { get; set; }
        public DateTime DateSubmitted { get; set; }
    }
}

我的下一个问题是我的控制器。其实有两个问题。首先,正如 Mindless 所提到的,我没有传入我的 Report 模型。但更大的问题是,我什至不应该一开始就传入我的 ViewModel!真的,我只需要传入我的 Report 模型,然后在操作中使用两个 .Include() 语句即可使其工作。同样,这是更新后的代码:

ReportController.cs

public ActionResult Report()
{
    var report = report_context.RequestType.Include(m => m.RequestType).Include(m => m.Urgency).ToList();
    return View(report);
}

最后,我需要更新我的视图以简单地接受模型(而不是 ViewModel)。通过这样做,它将通过外键访问表中的内容。此外,由于我将列出一系列报告,因此我也需要将其设为 IEnumerable。这是更新的代码:

Report.cshtml

@model IEnumerable<BugTracker.Models.Report>
@{
    ViewBag.Title = "Report";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Bugs and Changes</h2>
<table class="table table-bordered table-hover">
    <thread>
        <tr>
            <th>Issue Name</th>
            <th>Request Type</th>
            <th>Priority</th>
            <th>Bug Description</th>
            <th>URL</th>
            <th>Date Submitted</th>
        </tr>
    </thread>
    <tbody>
        @foreach (var report in Model)
        {
        <tr>
            <td>@Html.ActionLink(report.Name, "Edit", "Customers", new { id = report.ID }, null)</td>
            <td>@report.RequestType.RequestBC</td>
            <td>@report.Urgency.UrgencyLevel</td>
            <td>@report.Description</td>
            <td>@report.URL</td>
            <td>@report.DateSubmitted.ToShortDateString()</td>
        </tr>
        }
    </tbody>
</table>

感谢大家的帮助!我真的很感谢所有的建议!

【讨论】:

    【解决方案2】:

    如果您想在视图模型中显示报告列表,您需要列出一个 IEnumerable。视图模型的目的是从许多模型中收集您在视图中需要的所有信息。如果您想要模型的 IEnumerable,只需将其作为 IEnumerable 添加到您的视图模型中即可。

    你可以这样:

    NewReportViewModel.cs

    namespace BugTracker.ViewModels
    {
        public class NewReportViewModel
        {
            public IEnumerable<RequestType> RequestType { get; set; }
            public IEnumerable<Urgency> Urgency { get; set; }
            public IEnumerable<Report> Reports { get; set; }
        }
    }
    

    在控制器中:

    public ActionResult Report()
        {
            var viewModel = new NewReportViewModel
            {
                RequestType = _context.RequestType.ToList(),
                Urgency = _context.Urgency.ToList(),
                Reports = _context.Reports.ToList() //Add whatever logic 
            };
            return View(viewModel);
        }
    

    然后在你的 foreach 循环中你可以这样做:

    @foreach (var report in Model.Reports)
            {
            <tr>
                <td>@Html.ActionLink(report.Name, "Edit", "Customers", new { id = report.ID }, null)</td>
                <td>@report.RequestType.RequestBC</td>
                <td>@report.Urgency.UrgencyLevel</td>
                <td>@report.Description</td>
                <td>@report.URL</td>
                <td>@report.DateSubmitted.ToShortDateString()</td>
            </tr>
            }
    

    【讨论】:

      【解决方案3】:

      首先,您没有在视图模型中传递“报告”,因此您可能需要添加它。

      其次你可以做类似的事情

      @foreach (var requstType in Model.RequestType)
      {
          ...
          //list of RequestBCs
          <td>@requestType.RequestBC</td>
          ...
      }
      
      @foreach (var urgency in Model.Urgency) 
      {
         ...
         //list of Urgencies
         <td>@urgency.UrgencyLevel</td>
         ...
      }
      

      因为它们都是 IEnumerable,但模型本身不是 IEnumerable,所以你不能这样做

      //Model isn't IEnumerable, so you can't loop this
      @foreach (var report in Model)
      {
          ...
          //both of these are IEnumrables
          <td>@report.RequestType.RequestBC</td>
          <td>@report.Urgency.UrgencyLevel</td>
          ...
      }
      

      这是我的解决方案:

      首先,您的报告应该是 IEnumerable

      public class NewReportViewModel
      {
          public IEnumerable<RequestType> RequestType { get; set; }
          public IEnumerable<Urgency> Urgency { get; set; }
          public IEnumerable<Report> Report { get; set; }
      }
      

      然后,将 Report 添加到您的 ViewModel:

      public ActionResult Report()
      {
          var requestType = _context.RequestType.ToList();
          var urgency = _context.Urgency.ToList();
          var report = _context.Report.ToList(); //however you want to get it
          var viewModel = new NewReportViewModel
          {
              RequestType = requestType, //why do you need this, since it's already related to report, you want display a list of request types?
              Urgency = urgency, //and this?
              Report = report //you are missing report here
          };
          return View(viewModel);
      }
      

      那么在你看来:

      @foreach(var report in Model.Report)
      {
          <tr>
              <td>@Html.ActionLink(report.Name, "Edit", "Customers", new { id = report.ID }, null)</td>
              //I'm confused here, do you want to display a list of RequstTypes/UrgencyLevels or just one related to report?
              <td>@report.RequestType.RequestBC</td>
              <td>@report.UrgencyLevel</td>
      
              <td>@report.Description</td>
              <td>@report.URL</td>
              <td>@report.DateSubmitted.ToShortDateString()</td>
          </tr>
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-03-22
        • 1970-01-01
        • 1970-01-01
        • 2022-01-04
        • 2018-06-25
        • 2021-09-18
        • 1970-01-01
        • 2012-04-19
        相关资源
        最近更新 更多