无法显示ViewModel的所有字段

时间:2018-08-16 16:43:58

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

我要完成的工作是在View中显示所有字段。目前,我已经建立了一个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模型不是IEnumberable的(ememable)(我也不认为我可以做到)。

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

如何查看同时包含IEnumerable字段和非IEnumerable字段的ViewModel,并显示所有字段?我需要更改什么?

3 个答案:

答案 0 :(得分:1)

感谢大家的帮助!我查看了几个资源,最后通过研究Mosh的MVC Udemy课程获得了答案。首先,我的NewReportViewModel.cs,Urgency.cs或RequestType.cs ViewModels和Models没有任何问题。但是,此后所有问题都出现了。首先,让我们从Report.cs开始...

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

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>

感谢大家的帮助!我非常感谢所有建议!

答案 1 :(得分:0)

如果要在视图模型中显示报告列表,则需要列出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>
        }

答案 2 :(得分:0)

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

第二,您可以做类似

的操作
@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,但是Model本身不是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>
}