我正在尝试使用新的 Razor SDK 将我的视图包含在我的类库中,其中每个类库都是一个 MVC 区域。如果我在我的类库中包含带有区域目录的视图,例如
/MyLibrary/Areas/MyLibrary/Views/Home/Index.cshtml
然后它加载正常。但是我不喜欢我必须将它们放在区域目录中,理想情况下路径是:
/MyLibrary/Views/Home/Index.cshtml
我猜我必须使用视图位置扩展器来实现这一点。但是,我不知道如何为包含在类库中而不是包含在应用程序中的视图实现此目的。到目前为止,我已经想出了:
public class AreaViewLocationExpander : IViewLocationExpander {
public virtual IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations) {
return viewLocations.Concat(new[] {
"../{2}/Views/{1}/{0}" + RazorViewEngine.ViewExtension
});
}
public virtual void PopulateValues(ViewLocationExpanderContext context) { }
}
这将引发错误:
无效操作异常:找不到视图"索引"。这 搜索了以下位置:
/Areas/MyLibrary/Views/Home/Index.cshtml
/Areas/MyLibrary/Views/Shared/Index.cshtml
/views/Shared/Index.cshtml
/Pages/Shared/Index.cshtml
/../MyLibrary/Views/Home/Index.cshtml
但我想即使它确实在本地工作,它也不会在生产中或当库打包在 NuGet 包中时。
如果有人能告诉我如何实现这一目标,我将不胜感激。谢谢
步骤 1
从 GitHub 上的@pranavkm:
Razor SDK 使用众所周知的 MSBuild 元数据来计算项目 相对路径。您可以为文件和 Razor 设置链接元数据 会使用它。例如,将其添加到您的项目文件中将 更新所有 CSHTML 文件以具有项目的视图引擎路径 名称作为前缀:
<Target Name="UpdateTargetPath" BeforeTargets="AssignRazorGenerateTargetPaths">
<ItemGroup>
<RazorGenerate Include="@(RazorGenerate)" Link="$(TargetName)%(RazorGenerate.RelativeDir)%(RazorGenerate.FileName)%(RazorGenerate.Extension)" />
</ItemGroup>
</Target>
这不适用于运行时编译 - 即如果你要 将其应用于Application.csproj,它将适用于编译的构建时 视图,但运行时编译的视图将继续使用/views/home/index.cshtml
步骤 2
然后,您需要添加以下IViewLocationExpander:
public class AreaViewLocationExpander : IViewLocationExpander {
public virtual IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations) {
return viewLocations.Concat(new[] {
"/{2}/Views/{1}/{0}" + RazorViewEngine.ViewExtension
});
}
public virtual void PopulateValues(ViewLocationExpanderContext context) { }
}