【问题标题】:C# MVC Return ViewModel to ListC# MVC 将 ViewModel 返回到列表
【发布时间】:2021-01-09 01:41:26
【问题描述】:

我决定发布一个新问题,而不是添加到现有问题,因为这不是同一个问题。我按照对另一个问题的评论创建了一个 ViewModel。

到目前为止,我还没有必须从 ViewModel 中列出。我确实在网上搜索过,看看是否能找到一个例子,但我发现的只是;如何在 ViewModel 中创建列表,我已经知道该怎么做了。

我在下面有一个 ViewModel。我不确定它的结构是否正确,但控制器正在返回count = 0

控制器:

    public ActionResult Index()
    {
        List<AccountingViewModels> list = new List<AccountingViewModels>();
        return View(list);
    }

视图有这个:@model IEnumerable&lt;BestenEquipment.Models.AccountingViewModels&gt;

我确实尝试过这样做@model List&lt;BestenEquipment.Models.AccountingViewModels&gt;

但出现错误 'List&lt;AccountingViewModels&gt;' does not contain a definition for 'Description' and no extension method 'Description' accepting a first argument of type 'List&lt;AccountingViewModels&gt;' could be found (are you missing a using directive or an assembly reference?)

控制器仍然是count = 0

IEnumerable 不会出错,它只是给了我一个空表。所以我认为 IEnumerable 是要走的路。我只需要修复控制器。

如果有人能指出我正确的方向或告诉我我的控制器有什么问题,那将有很大帮助。

这是视图模型:

public class AccountingViewModels
{
    [Key]
    public Guid TransactionId { get; set; }
    public string Description { get; set; }
    [Display(Name = "Company")]
    public int? CompanyId { get; set; }
    [Display(Name = "Vendor")]
    public Guid? VendorId { get; set; }
    [Display(Name = "Rec Chk #")]
    public string InCheckNumber { get; set; }
    [Display(Name = "Sent Chk #")]
    public string OutCheckNumber { get; set; }
    [Display(Name = "Invoice #")]
    public string InvoiceNumber { get; set; }
    [Display(Name = "PO #")]
    public string PurchaseOrderNumber { get; set; }
    [Display(Name = "Ledger Acct")]
    public Guid LedgerAccountId { get; set; }
    [Display(Name = "Credit")]
    public decimal? DebitAmount { get; set; }
    [Display(Name = "Debit")]
    public decimal? CreditAmount { get; set; }
    [Display(Name = "Transaction")]
    [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = false)]
    public DateTime TransactionDate { get; set; }
    [Display(Name = "Modified By")]
    public string ModifiedBy { get; set; }
    [Display(Name = "Modified")]
    [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = false)]
    public DateTime? ModifiedDate { get; set; }
    public string SavedDocument { get; set; }
    [Display(Name = "Created")]
    [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = false)]
    public DateTime CreatedDate { get; set; }
    [Display(Name = "Created By")]
    public string CreatedBy { get; set; }
    public bool IsCredit { get; set; }
    public bool IsDebit { get; set; }
    public Guid Type { get; set; }

    [ForeignKey("LedgerAccountId")]
    public LedgerAccount LedgerAccount { get; set; }
    [ForeignKey("CompanyId")]
    public CompanyNames Company { get; set; }
    [ForeignKey("VendorId")]
    public Vendors Vendor { get; set; }
}

这很可能是一个简单的修复,我只需要轻推一下..

使用db模型是这样的:return View(db.Transaction.ToList());

我需要做同样的事情,但要使用 ViewModel..

感谢您的帮助!

谢谢

更新:

这是我的原始问题的链接,并被告知要创建一个 viewModel.. Original Issue

更新:

添加视图:

@model List<BestenEquipment.Models.AccountingViewModels>
@{
   Layout = "~/Views/Shared/_DashboardLayout.cshtml";
}


@section ScriptsOrCss
{
    @Html.Action("DataTableCssJs", "Layout")
}
@Html.ValidationSummary(true, "", new { @class = "text-danger" })

<section class="content-header">
<h1>
    Overview List
    <small> Transactions </small>
</h1>
</section>
<section class="content">
<!-- Small boxes (Stat box) -->
<div class="row">
    <div class="col-md-12">
        @if (ViewBag.Create == true)
        {
            <div class="box box-solid box-primary">
                <div class="box-body">
                    <!-- Split button -->
                    <div class="margin">
                        <div class="btn-group">
                            @Ajax.ModalDialogActionLink("Create Quick", "Create", "Create ", "btn btn-info btn-sm")
                        </div>
                        <div class="btn-group">
                            <a href="~/Tranaction/Create" class="btn btn-warning btn-sm">Create Full</a>
                        </div>
                    </div>
                    <!-- flat split buttons -->
                </div><!-- /.box-body -->
            </div>
        }

        <div class="box box-primary">
            <div class="box-header">
                <h3 class="box-title">Orders</h3>
            </div><!-- /.box-header -->
            <div class="box-body table-responsive">
                <table class="table table-striped table-hover table-bordered" id="TransactionListTable">
                    <thead>
                        <tr>
                            <th>
                                @Html.DisplayNameFor(model => model.Description)
                            </th>
                            <th>
                                @Html.DisplayNameFor(model => model.Company.CompanyName)
                            </th>
                            <th>
                                @Html.DisplayNameFor(model => model.Vendor.Name)
                            </th>
                            <th>
                                @Html.DisplayNameFor(model => model.InCheckNumber)
                            </th>
                            <th>
                                @Html.DisplayNameFor(model => model.OutCheckNumber)
                            </th>
                            <th>
                                @Html.DisplayNameFor(model => model.InvoiceNumber)
                            </th>
                            <th>
                                @Html.DisplayNameFor(model => model.PurchaseOrderNumber)
                            </th>
                            <th>
                                @Html.DisplayNameFor(model => model.LedgerAccountId)
                            </th>
                            <th>
                                @Html.DisplayNameFor(model => model.DebitAmount)
                            </th>
                            <th>
                                @Html.DisplayNameFor(model => model.CreditAmount)
                            </th>
                            <th>
                                @Html.DisplayNameFor(model => model.TransactionDate)
                            </th>
                            <th>
                                CRUD
                            </th>
                            <th>
                                Actions
                            </th>
                        </tr>
                    </thead>
                    <tbody>
                        @foreach (var item in Model.Items)
                        {
                        <tr>
                            <td>
                                @Html.DisplayFor(modelItem => item.Description)
                            </td>
                            <td>
                                @if (item.CompanyId != null)
                                {
                                    @Html.DisplayFor(modelItem => item.Company.CompanyName)
                                }
                                else
                                {
                                    <b>N/A</b>
                                }

                            </td>
                            <td>
                                @if (item.VendorId != null)
                                {
                                    @Html.DisplayFor(modelItem => item.Vendor.Name)
                                }
                                else
                                {
                                    <b>N/A</b>
                                }

                            </td>
                            <td>
                                @if (item.InCheckNumber != null)
                                {
                                    @Html.DisplayFor(modelItem => item.InCheckNumber)
                                }
                                else
                                {
                                    <b>N/A</b>
                                }
                            </td>
                            <td>
                                @if (item.OutCheckNumber != null)
                                {
                                    @Html.DisplayFor(modelItem => item.OutCheckNumber)
                                }
                                else
                                {
                                    <b>N/A</b>
                                }

                            </td>
                            <td>
                                @if (item.InvoiceNumber != null)
                                {
                                    @Html.DisplayFor(modelItem => item.InvoiceNumber)
                                }
                                else
                                {
                                    <b>N/A</b>
                                }

                            </td>
                            <td>
                                @if (item.PurchaseOrderNumber != null)
                                {
                                    @Html.DisplayFor(modelItem => item.PurchaseOrderNumber)
                                }
                                else
                                {
                                    <b>N/A</b>
                                }
                            </td>
                            <td>
                                @Html.DisplayFor(modelItem => item.LedgerAccount.Title)
                            </td>
                            <td>
                                @if (item.IsDebit == true)
                                {
                                    @Html.DisplayFor(modelItem => item.DebitAmount)
                                }
                                else
                                {
                                    <b>N/A</b>
                                }

                            </td>
                            <td>
                                @if (item.IsCredit == true)
                                {
                                    @Html.DisplayFor(modelItem => item.CreditAmount)
                                }
                                else
                                {
                                    <b>N/A</b>
                                }
                            </td>
                            <td>
                                @Html.DisplayFor(modelItem => item.TransactionDate)
                            </td>
                            <td>

                                @if (ViewBag.Edit == true)
                                {
                                    @Ajax.ModalDialogActionLink("Edit", "Edit", "Edit", "btn btn-warning btn-sm", new { id = item.TransactionId })
                                }

                                @if (ViewBag.Read == true)
                                {
                                    @Ajax.ModalDialogActionLink("Details", "Details", "Transaction Details", "btn btn-info btn-sm", new { id = item.TransactionId })
                                }

                                @if (ViewBag.Delete == true)
                                {
                                    @Ajax.ActionLink("Delete", "Delete", "Tranaction", new { id = item.TransactionId },
                                             new AjaxOptions()
                                             {
                                                 HttpMethod = "Delete",
                                                 Confirm = "Are you sure you want to delete " + item.Description + "Transaction",
                                             }, new { @class = "btn btn-danger btn-sm Delete" })
                                }
                            </td>
                            <td>
                            
                            </td>
                        </tr>

                        }
                    </tbody>
                </table>
            </div>
        </div>
    </div>
</div>

【问题讨论】:

  • 您尚未分享您的视图,但您的视图中似乎在说Model.Description,而您应该说foreach (var item in Model) { item.Description }
  • @Noah 我可以添加我的视图,但是控制器没有填充任何内容,这是我的视图`@Html.DisplayFor(modelItem => item.Description)`
  • 我认为模型不能是 IEnumerable 或 List。它必须是一个普通的对象。您可以创建模型类并将这个 Ienumerable 作为属性放入模型中。
  • @Sreenath 我想我以前做过,但不是我需要的。我最初遇到的问题是显示一个列表,其中包含另一个数据库中另一个表中的几列。但是,我被告知要创建一个 viewModel。列显示为空。原始问题已添加到上述问题中。
  • 您编写的谓词看起来不太正确,因为您的一侧有modelItem,另一侧有item。无论如何,由于您的模型是AccountingViewModelss 的集合,因此您确实在尝试引用不存在的collectionDescription 属性。它是集合中每个项目 的属性。这就是那个错误的原因。这与控制器或集合的空虚无关。

标签: c# asp.net-mvc


【解决方案1】:

我复制了你的错误。试试这个。

而不是这个:

@model List<BestenEquipment.Models.AccountingViewModels>

使用这个:

@model IEnumerable<BestenEquipment.Models.AccountingViewModels>

最后,删除 foreach 循环中的 Items 字样,它应该是:

@foreach (var item in Model)

【讨论】:

  • 其实昨晚我发现为什么它给了我那个错误..这不是循环它是列标题:@Html.DisplayNameFor(model => model.Description) 和描述是第一个标题..
  • 我仍然无法用我得到的答案填充此视图。我可能倾向于使用 MSSQL 视图来填充视图。似乎这是一个更简单的选择,因为我没有在视图和模型本身中得到明确的答案。
  • 我之前也试过那个。我已经创建了一个 SQL 视图,一旦我得到它,我将在一个答案中分享它。毕竟数据库应该做正确的工作!
【解决方案2】:
Public class AcctModel
{
public IEnumerable<AccountingViewModels> Items {get; set;}
}

在view.cshtml中

foreach(var item in Model.Items)
{
// Your code here
}

【讨论】:

  • 只用一个空控制器'return View();'试过这个但是我得到了同样的错误:''List'不包含'Description'的定义,并且找不到接受'List'类型的第一个参数的扩展方法'Description'(您是否缺少使用指令还是程序集引用?)'
【解决方案3】:

我发现当您只是列出记录时,使用 SQL 视图会更容易。没有任何创建或编辑,因此只需填充您需要的内容就更容易了。数据库的工作就是完成这项工作,所以为什么不让它呢!

这是我所做的,以防有人需要这样的东西或正在寻找一种更清洁的方式来做这件事。 请记住,我需要来自 2 个单独数据库中的表的联接。在同一个数据库中创建视图更容易,您只需选择表,然后选择所需的字段。

首先创建视图,在我的情况下,我需要使用别名进行查询并且没有使用 GUI。

SQL:

SELECT        t.TransactionId, t.Description, t.InCheckNumber, t.OutCheckNumber, t.InvoiceNumber, t.PurchaseOrderNumber, la.Title, t.DebitAmount, t.CreditAmount, t.TransactionDate, t.SavedDocument, t.CreatedDate, t.CreatedBy, tt.Type, 
                     cn.CompanyName, v.Name
FROM            dbo.LedgerAccount AS la INNER JOIN
                     dbo.[Transaction] AS t ON la.LedgerAccountId = t.LedgerAccountId 
INNER JOIN
                     dbo.TransactionType AS tt ON t.Type = tt.TypeId INNER JOIN
                     OtherDBName.dbo.CompanyNames AS cn ON t.CompanyId = 
cn.CompanyId LEFT OUTER JOIN
                     OtherDbName.dbo.Vendors AS v ON t.VendorId = v.VendorId

我将 Transaction 表 t 将 Type 表称为 tt,当您引用另一个数据库时,您必须使用 dbname.schema.table.column 这些我为 CompanyNames 表命名为 cn 和 @987654325 @ 代表供应商表。在我的特殊情况下,我不会总是在每条记录中都有供应商名称,因此您可以使用 LEFT OUTER JOIN
创建完成后,您现在可以返回项目并创建实体。

在您的上下文中,您将创建它,就好像它只是另一个表一样。除了不映射它。没有必要。我们不会将其用于 CRUD 操作。 我将视图称为 TransactionsView:

public class AccountingEntities : DbContext
{
    public AccountingEntities() : base("AccountingConnection")
    {
    }

    [NotMapped]
    public IDbSet<TransactionsView> TransactionsView { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
    }
}

用途:

using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.ComponentModel.DataAnnotations.Schema;

然后创建模型TranactionsView

using System;
using System.ComponentModel.DataAnnotations;

namespace YourProject.AccountingDTO.Entities
{
public class TransactionsView
{
    [Key]
    public Guid TransactionId { get; set; }
    [Display(Name = "Desc")]
    public string Description { get; set; }
    [Display(Name = "Company")]
    public string CompanyName { get; set; }
    [Display(Name = "Vendor")]
    public String Name { get; set; }
    [Display(Name = "Rec Chk #")]
    public string InCheckNumber { get; set; }
    [Display(Name = "Sent Chk #")]
    public string OutCheckNumber { get; set; }
    [Display(Name = "Invoice #")]
    public string InvoiceNumber { get; set; }
    [Display(Name = "PO #")]
    public string PurchaseOrderNumber { get; set; }
    [Display(Name = "Ledger Acct")]
    public string Title { get; set; }
    [Display(Name = "Credit")]
    public decimal? DebitAmount { get; set; }
    [Display(Name = "Debit")]
    public decimal? CreditAmount { get; set; }
    [Display(Name = "Transaction")]
    [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = false)]
    public DateTime TransactionDate { get; set; }
    [Display(Name = "Doc Link")]
    public string SavedDocument { get; set; }
    [Display(Name = "Created")]
    [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = false)]
    public DateTime CreatedDate { get; set; }
    [Display(Name = "Created By")]
    public string CreatedBy { get; set; }
    [Display(Name = "Type")]
    public string Type { get; set; }
    }
}

控制器中的:

    private readonly AccountingEntities account = new AccountingEntities();
    // GET: Transaction
    public ActionResult Index()
    {
        return View(account.TransactionsView.ToList());
    }

在视图中,您只需创建一个列表视图并将@model 放在顶部:

@model IEnumerable<YourProject.AccountingDTO.Entities.TransactionsView>

如果我遗漏了一些我可以回答您可能有的任何问题的内容,我会尽量做到彻底。我一直将这些用于列表视图和表格

【讨论】:

  • P.S.这是我第一次尝试使用 2 个数据库进行 SQLView。如果数据库在不同的服务器上,这会有所不同。就我而言,它们在同一台服务器上..
猜你喜欢
  • 1970-01-01
  • 2013-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-18
  • 1970-01-01
相关资源
最近更新 更多