asp.net-mvc – 在EditorFor for child对象中使用时,MVC无法覆盖EditorTemplate的名称

我试图使用EditorTemplate在父视图中的表中显示一个子集合.我遇到的问题是,如果模板的命名与孩子的类完全相同,这只会起作用.当我尝试使用稍有不同名称的模板,并将该名称作为TemplateFor参数传递给EditorFor时,会收到运行时错误.我希望我可以使用不同的孩子EditorTemplates与不同的目的与同一个孩子集合.
这是一个简短的例子:

楷模:

public class Customer
{
  int id { get; set; }
  public string name { get; set; }

  public List<Order> Orders { get; set; }
}
public class Order
{
    public int id { get; set; }
    public DateTime orderdate { get; set; }
    public decimal amount { get; set; }

    public Customer customer { get; set; }
}

客户控制器Index()方法:

public ActionResult Index()
{
  Customer customer = new Customer() {id = 1,name = "Acme Corp.",Orders = new List<Order>()};
  customer.Orders.Add(new Order() {id = 1,orderdate = DateTime.Now,amount = 100M});
  customer.Orders.Add(new Order() { id = 2,amount = 200M });
  return View(customer);
}

客户Index.cshtml视图:

@model TemplateTest.Customer

@{
  Layout = null;
}

<!DOCTYPE html>

<html>
<head>
  <meta name="viewport" content="width=device-width" />
  <title>Customer</title>
</head>
<body>
  <div>
      @Html.EditorFor(Model=>Model.name)

      <table>
      <thead>
          <tr>
              <th>Order ID</th>
              <th>Order Date</th>
              <th>Amount</th>
          </tr>
      </thead>
          @Html.EditorFor(Model=>Model.Orders)
      </table>

  </div>
</body>
</html>

在View / Shared / EditorTemplates中添加了Order.cshmtl模板(添加了“color”来验证我正在使用此模板):

@model TemplateTest.Order

<tr>
  <td>@Html.DisplayFor(Model=>Model.id)</td>
  <td style="color:blue">@Html.EditorFor(Model=>Model.orderdate)</td>
  <td>@Html.EditorFor(Model=>Model.amount)</td>
</tr>

这工作正常但是,如果我将EditorTemplate重命名为“OrderList.cshtml”,并将小孩EditorFor行更改为

@Html.EditorFor(Model=>Model.Orders,"OrderList")

当我再次运行它,我得到这个例外:

“传入字典的模型项目的类型为”System.Collections.Generic.List“1 [TemplateTest.Order]”,但是这个字典需要一个类型为“TemplateTest.Order”的模型项.

任何想法为什么EditorFor不使用我在“templateName”参数中指定的模板“OrderList”?否则,该参数是什么?

解决方法

TL;DR > Named templates don’t work with collections,use a foreach loop to work around it – See below for extensive details about why,and an example.

你说:

Any idea why the EditorFor doesn’t use the template “OrderList” I
specified in the “templateName” argument? Otherwise,what is that
argument for?

EditorFor实际上是使用你指定的模板OrderList,但是你已经偶然发现了一些令人困惑的事情.一些研究提出了很多提示,但是我在这篇文章中发现了真正的坚果和细节:Problem with MVC EditorFor named template

简而言之,发生的是默认的情况:@ Html.EditorFor(Model => Model.Orders)实际上是按照惯例在临时调用MVC默认模板,但这根本不是很明显.

尝试这样思考:

在工作版本中,您将传递一个类型列表< Order>参考Model.Orders(MANY orders),但模板是用Order(single,NOT MANY)模型指定的.

有趣.为甚么甚至工作?乍看起来好像不行.但是,由于幕后发生了什么,它确实有效.

从上述帖子改写:

When you use @Html.EditorFor(c => c.Orders) MVC convention chooses
the default template for IEnumerable. This template is part of the MVC framework,and what it does is generate Html.EditorFor() for
each item in the enumeration. That template then generates the
appropriate editor template for each item in the list individually
– in your case they’re all instances of Order,so,the Order template is used for each item.

这是魔法,它是方便的,但是因为这是惯例发生的,并且基本上是我们隐藏的,所以我认为是混乱的根源.

现在当你尝试做同样的事情,但使用一个命名的模板,通过显式设置你的EditorFor来使用一个特定的编辑器模板OrderList,你最终会传递整个枚举的编辑器模板 – 这是错误的根源发布.

换句话说,失败的案例设法跳过工作案例的“魔法”部分,这就是为什么它失败.但是,在语义上它看起来很好听,对吧?有混乱.

工作情况:

your call                                default MVC template      your template
@Html.EditorFor( Model => Model.Orders)  IEnumerable template      Order template

失败案件:

your call                                           your template
@Html.EditorFor(Model=>Model.Orders,"OrderList")   OrderList template       ERROR!!!

有很多方法可以使错误消失,但是其中许多方法是有问题的,因为它们导致HTML控件的渲染方式阻止您通过POST上的索引来处理单个控件. Uhhg. (注意:工作案例确实按原样正确呈现HTML)

为了正确渲染HTML控件,您似乎必须使用常规for循环(而不是foreach),并将每个单独的Order对象传递给自定义模板(我称之为OrderEditorTemplateDefault).

@for (int i = 0; i < Model.Orders.Count ; i++) 
{
    @Html.EditorFor(c => Model.Orders[i],"OrderEditorTemplateDefault")
}

部分你的问题表示:

I was hoping I could use different child EditorTemplates for different
purposes with the same child collection.

您可以通过在循环中引入条件并在其中选择替代模板(无论是对于整个列表还是按顺序排列,仅取决于如何编写条件)

@for (int i = 0; i < Model.Orders.Count ; i++) {
    if (someCondition) {
        @Html.EditorFor(c => Model.Orders[i],"OrderEditorTemplateDefault")
    } else {
        @Html.EditorFor(c => Model.Orders[i],"OrderEditorTemplateALTERNATE")
    }
}

对不起这么冗长希望有帮助.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


判断URL文件是不是在于在。private static bool UrlIsExist(string url){ System.Uri u = null; try { u = new Uri(url); } catch { return false; } bool isExist = false;
由于在.net中,Request时出现有HTML或Javascript等字符串时,系统会认为是危险性值。立马报错。解决方案一:在.aspx文件头中加入这句:解决方案二:修改web.config文件:因为validateRequest默认值为true。只要设为false即可。
public static bool ProcessIdCard(this string idCard, out DateTime birthday, out string genderName) { bool result; birthda...
如果你在GridView控件上设置 AllowPaging=&quot;true&quot; or AllowSorting=&quot;true&quot; 而没有使用使用数据源控件 DataSource (i.e. SqlDataSource, ObjectDataSource),运行则会出现下
protected void Page_Load(object sender, EventArgs e){ ScriptManager sm = Page.Master.FindControl(&quot;ScriptManager1&quot;) as ScriptManager; if (sm
1. install all features in IIS2. Try the following steps to register it.run %windir%\Microsoft.NET\Framework\v4.0.21006\aspnet_regiis.exe -i或运行,跳出如下错误
一般来说一个 HTML 文档有很多标签,比如“”、“”、“”等,想把文档中的 img 标签提取出来并不是一件容易的事。由于 img 标签样式变化多端,使提取的时候用程序寻找并不容易。于是想要寻找它们就必须写一个非常健全的正则表达式,不然有可能会找得不全,或者找出来的不是正确的 img 标签。我们可以
asp.net updatepanel 局部刷新,导致JS不能加载,而无法使用,而且 updatepanel会刷两次,郁闷的。解决方法如下:
FileHandlerhttp://www.cnblogs.com/vipsoft/p/3627709.htmlUpdatePanel无法导出下载文件:http://www.cnblogs.com/vipsoft/p/3298299.html//相对路径下载。path: ~/DownLoad///p
本地能上传文件,部署到服务器上就报Cannot access a closed file 错误,以下是解决方法: 最重要是requestLengthDiskThreshold此属性设置输入流缓冲阈值。
http://tool.oschina.net/commons字符十进制转义字符&quot;&amp;#34;&amp;quot;&amp;&amp;#38;&amp;amp;&amp;#62;&amp;gt;不断开空格(non-breaking space)&amp;#160;HTML特殊转义字符
1、2两步为推荐做法1. 将MySql.Data.dll放到 bin目录下面,或都安装mysql-connector-net-6.0.0.msi2.web.config 添加如下节点,注册版本号一致 3.全局配置在C:\WINDOWS\Microsoft.NET\Framework\v2.0.507
C# 跳转新页面string url = &quot;http://www.vipsoft.com.cn&quot;;ResponseRedirect.Redirect(Response, url, &quot;_blank&quot;, &quot;&#39;toolbar=0,scrollbar
.NET Core 在其上下文中,该请求的地址无效。 看了端口,发现没被占用,后来发现是IP地址变了 改成正确的IP就可以了。
datatable是一个jquery扩展的表格插件。其提供了强大的表格功能。官方地址:http://www.datatables.net/在官方示例中,对于表格的是否可排序是在初始化中设置的一个值来决定的$(&quot;.datatable-simplified&quot;).dataTable(
Html table 细边框 导航页档 军事 历史 ...
C# 跳转新页面判断URL文件是不是在于在。C# 指定物理目录下载文件,Response.End导致“正在中止线程”异常的问题public class FileHandler { public static bool DownLoadFile(string path, string fileName
由于将IE11升级到了 11 之前的网站无法正常使用,如果是开发人员碰到之问题,使用了微软的asp.net 控件,那么将服务器的.net framework 升级到 4.5http://www.microsoft.com/en-us/download/details.aspx?id=30653如果浏
引言 本文从Linux小白的视角, 在CentOS 7.x服务器上搭建一个Nginx-Powered AspNet Core Web准生产应用。 在开始之前,我们还是重温一下部署原理,正如你所常见的.Net Core 部署图: 在Linux上部署.Net Core App最好的方式是在Linux机器