Asp.Net 5 核心 DisplayFor() 发布错误
Asp.Net 5 Core DisplayFor() Publish Bug
我正在将一些代码从 Asp.net 4.7 移植到 Asp.Net 5 Core。该代码使用 foreach 语句循环遍历记录。它使用与 DisplayTemplates 文件夹中的类型匹配的旧版“DisplayTemplates”功能,根据模型为每个项目多态显示不同的 HTML。所有 classes 都来自相同的基础 class.
为了让它在 Asp.Net 5 Core 中正常工作,我不得不更改代码:
@foreach (var token in Model.TokenGraph)
{
@Html.DisplayFor(t => token)
}
至:
@foreach (var token in Model.TokenGraph)
{
@Html.DisplayFor(t => token, token.GetType().Name)
}
...传入类型的名称。
没问题,在我的本地机器上工作正常。
问题是当我将项目发布到远程服务器时,使用的模板始终默认为基础 class 模板。
奇怪的是,如果我将 token.GetType().Name 返回的字符串输出到页面,它匹配派生类型名称而不是基本类型名称。
这是 .Net Core 5 中的错误吗?如果没有解决方法,是否有更好的方法在 .Net 5 中处理此问题?
问题最终出现在 .csproj 文件中。不知何故,无论是从旧遗留项目的初始转换,还是之后移动文件。
只需删除下面的这些条目即可解决问题,因为 .Net Core 通常使用这些条目来排除文件(或修改它们的编译方式),这与旧版 .Net 不同。
<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>
顺便说一句,我意识到可以关闭 @Html.Display() 调用并使用动态命名的部分,如下所示。
@foreach (var token in Model.TokenGraph)
{
<partial name="@token.GetType().Name" model="token" />
}
唯一的变化是必须将文件向上移动到共享目录的顶层才能找到它们。这可以通过在启动文件中设置自定义位置来更好地管理,就像这样。
services.AddMvc().AddRazorOptions(options =>
{
options.PageViewLocationFormats.Add("/Pages/DisplayTemplates/{0}.cshtml");
});
这似乎更符合标准 CORE 和 .Net 5,现在 Html Helpers 即将淘汰。
我正在将一些代码从 Asp.net 4.7 移植到 Asp.Net 5 Core。该代码使用 foreach 语句循环遍历记录。它使用与 DisplayTemplates 文件夹中的类型匹配的旧版“DisplayTemplates”功能,根据模型为每个项目多态显示不同的 HTML。所有 classes 都来自相同的基础 class.
为了让它在 Asp.Net 5 Core 中正常工作,我不得不更改代码:
@foreach (var token in Model.TokenGraph)
{
@Html.DisplayFor(t => token)
}
至:
@foreach (var token in Model.TokenGraph)
{
@Html.DisplayFor(t => token, token.GetType().Name)
}
...传入类型的名称。
没问题,在我的本地机器上工作正常。
问题是当我将项目发布到远程服务器时,使用的模板始终默认为基础 class 模板。
奇怪的是,如果我将 token.GetType().Name 返回的字符串输出到页面,它匹配派生类型名称而不是基本类型名称。
这是 .Net Core 5 中的错误吗?如果没有解决方法,是否有更好的方法在 .Net 5 中处理此问题?
问题最终出现在 .csproj 文件中。不知何故,无论是从旧遗留项目的初始转换,还是之后移动文件。
只需删除下面的这些条目即可解决问题,因为 .Net Core 通常使用这些条目来排除文件(或修改它们的编译方式),这与旧版 .Net 不同。
<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>
顺便说一句,我意识到可以关闭 @Html.Display() 调用并使用动态命名的部分,如下所示。
@foreach (var token in Model.TokenGraph)
{
<partial name="@token.GetType().Name" model="token" />
}
唯一的变化是必须将文件向上移动到共享目录的顶层才能找到它们。这可以通过在启动文件中设置自定义位置来更好地管理,就像这样。
services.AddMvc().AddRazorOptions(options =>
{
options.PageViewLocationFormats.Add("/Pages/DisplayTemplates/{0}.cshtml");
});
这似乎更符合标准 CORE 和 .Net 5,现在 Html Helpers 即将淘汰。