简体   繁体   English

Asp.Net 5 Core DisplayFor() 发布错误

[英]Asp.Net 5 Core DisplayFor() Publish Bug

I am porting some code from Asp.net 4.7 to Asp.Net 5 Core.我正在将一些代码从 Asp.net 4.7 移植到 Asp.Net 5 Core。 The code is using a foreach statement to loop through records.该代码使用 foreach 语句循环记录。 It is using the legacy "DisplayTemplates" functionality that matches types in the DisplayTemplates folder to polymorphically display different HTML for each item depending on the model.它使用与 DisplayTemplates 文件夹中的类型匹配的旧版“DisplayTemplates”功能,根据 model 为每个项目多态地显示不同的 HTML。 All classes are derived from the same base class.所有类都派生自相同的基础 class。

In order to get it to work correctly in Asp.Net 5 Core, I had to change the code from:为了让它在 Asp.Net 5 Core 中正常工作,我不得不将代码更改为:

 @foreach (var token in Model.TokenGraph)
 {
    @Html.DisplayFor(t => token)
 }

to:至:

 @foreach (var token in Model.TokenGraph)
 {
    @Html.DisplayFor(t => token, token.GetType().Name)
 }

... passing in the name of the type. ...传入类型的名称。

No problems problems and working correctly on my local machine.没有问题,并且在我的本地机器上正常工作。

The problem is when I publish the project to a remote server, the template used always defaults to the base class template.问题是当我将项目发布到远程服务器时,使用的模板始终默认为基本 class 模板。

Strangely enough, if I output the string returned by token.GetType().Name to the page, it matches the derived type name not the base type name.奇怪的是,如果我 output 将token.GetType().Name返回到页面的字符串匹配,它匹配派生类型名称而不是基类型名称。

Is this is a bug in.Net Core 5?这是.Net Core 5中的错误吗? If there is not a workaround, is there a better way to handle this in.Net 5?如果没有解决方法,在.Net 5 中是否有更好的方法来处理这个问题?

The issue ended up being in the.csproj file.问题最终出现在 .csproj 文件中。 Somehow, either from the initial conversion from the old legacy project, or from moving the files around afterwards.不知何故,要么来自旧遗留项目的初始转换,要么来自之后移动文件。

Simply removing these entries below fixed the issue as.Net Core generally uses the entries to excludes files (or modify how they are compiled), unlike legacy.Net.与 legacy.Net 不同,只需删除下面的这些条目即可解决问题,因为.Net Core 通常使用这些条目来排除文件(或修改它们的编译方式)。

  <ItemGroup>
    <Compile Remove="Pages\Shared\DisplayTemplates\**" />
    <Content Remove="Pages\Shared\DisplayTemplates\**" />
    <EmbeddedResource Remove="Pages\Shared\DisplayTemplates\**" />
    <None Remove="Pages\Shared\DisplayTemplates\**" />
  </ItemGroup>

  <ItemGroup>
    <Content Include="Pages\Shared\DisplayTemplates\Token.cshtml">
      <ExcludeFromSingleFile>true</ExcludeFromSingleFile>
      <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
    </Content>
  </ItemGroup>

  <ItemGroup>
    <None Include="Pages\Shared\DisplayTemplates\TextToken.cshtml" />
    ....
  </ItemGroup>

As an aside, I realized that it is possible to switch out the @Html.Display() call and use a dynamically named partial as below.顺便说一句,我意识到可以切换 @Html.Display() 调用并使用如下动态命名的部分。

 @foreach (var token in Model.TokenGraph)
 {
    <partial name="@token.GetType().Name" model="token" />
 }

The only change was that files had to be moved up to the top level of the Shared directory for them to be found.唯一的变化是必须将文件移动到共享目录的顶层才能找到它们。 This can be managed better by setting a custom location in the Startup file, like so.这可以通过在启动文件中设置自定义位置来更好地管理,就像这样。

services.AddMvc().AddRazorOptions(options =>
{
    options.PageViewLocationFormats.Add("/Pages/DisplayTemplates/{0}.cshtml");
});

This would seem to be more in line with standard CORE and.Net 5, now that Html Helpers are on the way out.这似乎更符合标准 CORE 和 .Net 5,因为 Html Helpers 即将推出。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM