You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在包含两个模型的ViewModel中使用@Html.DisplayNameFor?

MVC中Html.DisplayNameFor使用问题排查与解决

问题描述

作为MVC新手,无法正确在以下场景中使用Html.DisplayNameFor,已耗费2小时排查仍未解决,请求技术帮助。

Index.cshtml代码

@using MultipleModelInOneView;
@model  ViewModel
@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<div class="main-content">
    <div class="page-content">
        <div class="container-fluid">
            <div class="row">
                <div class="col-12">
                    <div class="card">
                        <div class="card-body">
                            <h4 class="card-title">Customer Enquiry Products</h4>
                            <p class="card-title-desc"></p>
                            <!-- Button trigger modal -->
                            <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal">
                                Open Create Modal
                            </button>

                            <div id="mymodal" class="popup">
                                @Html.Partial("~/Views/Shared/_CustomerEnquiryCreate.cshtml", this.Model.CustomerEnquiry)
                            </div>


                            <table id="datatable-buttons" class="table table-striped table-bordered dt-responsive nowrap" style="border-collapse: collapse; border-spacing: 0; width: 100%;">
                                <thead>
                                    <tr>
                                        <th>
                                            @Html.DisplayNameFor(model => model.TargetPrice)
                                        </th>
                                        <th>
                                            @Html.DisplayNameFor(model => model.Quantity)
                                        </th>
                                        <th>
                                            @Html.DisplayNameFor(model => model.LeadTime)
                                        </th>
                                        <th>
                                            @Html.DisplayNameFor(model => model.Category)
                                        </th>
                                        <th>
                                            @Html.DisplayNameFor(model => model.RoHSStatus)
                                        </th>
                                        <th>
                                            @Html.DisplayNameFor(model => model.SalesRep)
                                        </th>
                                        <th>
                                            @Html.DisplayNameFor(model => model.PackageCase)
                                        </th>
                                        <th>
                                            @Html.DisplayNameFor(model => model.Description)
                                        </th>
                                        <th>
                                            @Html.DisplayNameFor(model => model.Currency.Currency1)
                                        </th>
                                        <th>
                                            @Html.DisplayNameFor(model => model.CustomerEnquiry.SalesRep)
                                        </th>
                                        <th>
                                            @Html.DisplayNameFor(model => model.Product.PartNumber)
                                        </th>
                                        <th>
                                            @Html.DisplayNameFor(model => model.RFQManufactuer.Name)
                                        </th>
                                        <th></th>
                                    </tr>
                                </thead>
                                <tbody>
                                    @foreach (var item in Model)
                                    {
                                        <tr>
                                            <td>
                                                @Html.DisplayFor(modelItem => item.TargetPrice)
                                            </td>
                                            <td>
                                                @Html.DisplayFor(modelItem => item.Quantity)
                                            </td>
                                            <td>
                                                @Html.DisplayFor(modelItem => item.LeadTime)
                                            </td>
                                            <td>
                                                @Html.DisplayFor(modelItem => item.Category)
                                            </td>
                                            <td>
                                                @Html.DisplayFor(modelItem => item.RoHSStatus)
                                            </td>
                                            <td>
                                                @Html.DisplayFor(modelItem => item.SalesRep)
                                            </td>
                                            <td>
                                                @Html.DisplayFor(modelItem => item.PackageCase)
                                            </td>
                                            <td>
                                                @Html.DisplayFor(modelItem => item.Description)
                                            </td>
                                            <td>
                                                @Html.DisplayFor(modelItem => item.Currency.Currency1)
                                            </td>
                                            <td>
                                                @Html.DisplayFor(modelItem => item.CustomerEnquiry.SalesRep)
                                            </td>
                                            <td>
                                                @Html.DisplayFor(modelItem => item.Product.PartNumber)
                                            </td>
                                            <td>
                                                @Html.DisplayFor(modelItem => item.RFQManufactuer.Name)
                                            </td>
                                            <td>
                                                @Html.ActionLink("Edit", "Edit", new { id = item.EnqProdID }) |
                                                @Html.ActionLink("Details", "Details", new { id = item.EnqProdID }) |
                                                @Html.ActionLink("Delete", "Delete", new { id = item.EnqProdID })
                                            </td>
                                        </tr>
                                    }
                                </tbody>
                            </table>
                        </div>
                    </div>
                </div>
                <!-- end col -->
            </div>
            <!-- end row -->
        </div>
        <!-- end main content-->
    </div>
    <!-- END layout-wrapper -->
</div>

ViewModel代码

using REScrmNov22.Data;
using REScrmNov22.Models;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web;

namespace MultipleModelInOneView
{
    public class ViewModel
    {
        public IEnumerable<CustEnquiryProduct> CustEnquiryProduct { get; set; }
        public IEnumerable<CustomerEnquiry> CustomerEnquiry { get; set; }
    }

}

Index动作方法代码

public ActionResult Index()
{
    var custEnquiryProducts = db.CustEnquiryProducts.Include(c => c.Currency).Include(c => c.CustomerEnquiry).Include(c => c.Product).Include(c => c.RFQManufactuer);

    var customerEnquiries = db.CustomerEnquiries.Include(c => c.Customer).Include(c => c.EnquiryStatu);

    ViewModel mymodel = new ViewModel();
    mymodel.CustEnquiryProduct = custEnquiryProducts.ToList();
    mymodel.CustomerEnquiry = customerEnquiries.ToList();

    return View(mymodel.CustEnquiryProduct);
}

问题根源

  1. 视图模型与传递的模型不匹配:视图声明的模型是ViewModel,但控制器返回的是mymodel.CustEnquiryProduct(即IEnumerable<CustEnquiryProduct>),导致视图中model => model.TargetPrice这类表达式找不到对应属性——因为IEnumerable<CustEnquiryProduct>本身没有TargetPrice属性,只有集合里的单个元素才有。
  2. Html.DisplayNameFor需要针对单个实体类型获取显示名称,而不是集合类型。

修复步骤

步骤1:修正控制器返回的模型

控制器应该返回完整的ViewModel实例,而不是其中的集合:

public ActionResult Index()
{
    var custEnquiryProducts = db.CustEnquiryProducts.Include(c => c.Currency).Include(c => c.CustomerEnquiry).Include(c => c.Product).Include(c => c.RFQManufactuer);

    var customerEnquiries = db.CustomerEnquiries.Include(c => c.Customer).Include(c => c.EnquiryStatu);

    ViewModel mymodel = new ViewModel();
    mymodel.CustEnquiryProduct = custEnquiryProducts.ToList();
    mymodel.CustomerEnquiry = customerEnquiries.ToList();

    // 返回完整的ViewModel,而不是集合
    return View(mymodel);
}

步骤2:修正视图中的模型遍历和DisplayNameFor调用

视图中需要遍历Model.CustEnquiryProduct集合,并且DisplayNameFor要针对集合中的单个元素类型来获取名称:

<!-- 修改thead部分的DisplayNameFor -->
<thead>
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.CustEnquiryProduct.FirstOrDefault().TargetPrice)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.CustEnquiryProduct.FirstOrDefault().Quantity)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.CustEnquiryProduct.FirstOrDefault().LeadTime)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.CustEnquiryProduct.FirstOrDefault().Category)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.CustEnquiryProduct.FirstOrDefault().RoHSStatus)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.CustEnquiryProduct.FirstOrDefault().SalesRep)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.CustEnquiryProduct.FirstOrDefault().PackageCase)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.CustEnquiryProduct.FirstOrDefault().Description)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.CustEnquiryProduct.FirstOrDefault().Currency.Currency1)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.CustEnquiryProduct.FirstOrDefault().CustomerEnquiry.SalesRep)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.CustEnquiryProduct.FirstOrDefault().Product.PartNumber)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.CustEnquiryProduct.FirstOrDefault().RFQManufactuer.Name)
        </th>
        <th></th>
    </tr>
</thead>
<tbody>
    <!-- 修改遍历对象为Model.CustEnquiryProduct -->
    @foreach (var item in Model.CustEnquiryProduct)
    {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.TargetPrice)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Quantity)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.LeadTime)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Category)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.RoHSStatus)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.SalesRep)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.PackageCase)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Description)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Currency.Currency1)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.CustomerEnquiry.SalesRep)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Product.PartNumber)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.RFQManufactuer.Name)
            </td>
            <td>
                @Html.ActionLink("Edit", "Edit", new { id = item.EnqProdID }) |
                @Html.ActionLink("Details", "Details", new { id = item.EnqProdID }) |
                @Html.ActionLink("Delete", "Delete", new { id = item.EnqProdID })
            </td>
        </tr>
    }
</tbody>

补充说明

  • FirstOrDefault()只是用来让编译器识别出集合元素的类型,实际运行时如果集合为空也不会报错,因为DisplayNameFor只解析表达式的元数据,不会执行方法。
  • 如果不想用FirstOrDefault(),也可以直接指定类型来获取显示名称:
    @Html.DisplayNameFor(model => new CustEnquiryProduct().TargetPrice)
    
  • 确保CustEnquiryProduct类的属性上已经通过[Display(Name = "XXX")]特性设置了显示名称,否则DisplayNameFor会直接返回属性名。

内容的提问来源于stack exchange,提问作者Thomas_AndGateSystems

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 01:45:30