MVC Core 2.0中DisplayTemplates多模板使用异常问题求助
在ASP.NET Core 2.0中使用DisplayTemplates多模板的正确姿势
我之前也踩过这个坑!在ASP.NET Core 2.0里,DisplayTemplates的多模板匹配逻辑确实和MVC5有差异,尤其是同一模型想用不同模板的场景,很容易出现你遇到的那种指定模板名无效、报错的问题。下面给你梳理一下正确的用法和解决步骤:
首先排查常见问题点
1. 确认模板的@model声明正确
不管是默认模板还是自定义模板,顶部的@model声明必须准确对应你的模型类型,比如ProductDtoPrintView.cshtml的开头一定要写:
@model YourProjectNamespace.ProductDto
如果命名空间或者模型名写错,框架会找不到匹配的模板,直接抛出500错误,这是最容易忽略的点。
2. 模板文件的路径和命名要规范
模板文件的放置路径和MVC5一致:
- 放在对应控制器的目录下:
Views/Product/DisplayTemplates/ProductDtoPrintView.cshtml - 或者全局共享目录:
Views/Shared/DisplayTemplates/ProductDtoPrintView.cshtml
注意文件名要和你调用时指定的模板名完全一致(Windows系统大小写不敏感,但Linux/Mac下敏感,尽量统一大小写避免坑)。
正确的调用方式
单个对象渲染
如果是单个ProductDto对象,直接指定模板名即可:
@Html.DisplayFor(m => m.Product, "ProductDtoPrintView")
集合对象渲染
如果是IEnumerable<ProductDto>集合,调用方式和单个对象一样,框架会自动遍历集合中的每个元素,应用你指定的模板:
@Html.DisplayFor(m => m.Products, "ProductDtoPrintView")
不需要在模板里写foreach,框架会帮你处理循环逻辑,这一点和MVC5是一致的。
解决指定模板名无效的问题
如果按照上面的步骤还是出现指定模板名返回默认模板,或者报错的情况,可以试试下面的方法:
- 直接指定模板文件路径:绕开模板名称匹配逻辑,直接用相对路径指定模板文件,比如:
这种方式在Core里是完全支持的,能确保框架加载到你想要的模板。@Html.DisplayFor(m => m.Product, "~/Views/Product/DisplayTemplates/ProductDtoPrintView.cshtml") - 清理视图缓存:Core 2.0开发环境默认禁用视图缓存,但有时候可能存在缓存残留,试试重启应用,或者删除项目的
obj和bin目录后重新编译。 - 升级到更高版本的ASP.NET Core:Core 2.0本身存在一些视图模板匹配的小bug,在2.1及以上版本中已经修复,升级后能解决大部分这类兼容性问题。
为什么MVC5可以而Core 2.0不行?
ASP.NET Core的Razor视图引擎重新设计了模板匹配逻辑,和MVC5的旧引擎相比,对模板名称的匹配优先级做了调整。在Core 2.0中,当同一模型存在多个模板时,框架的匹配逻辑不够灵活,容易出现“优先匹配默认模板(和模型同名的)而忽略指定模板名”的问题,这个问题在后续版本中得到了修复。
内容的提问来源于stack exchange,提问作者akd
相关产品推荐
相关产品推荐

