【问题标题】:Adding asp.net controllers/views from a Class Library从类库中添加 asp.net 控制器/视图
【发布时间】:2023-02-25 07:46:52
【问题描述】:
我正在使用 .NET 6(可能是 7)在 C# 中构建一个类库,以用于 ASP.NET Core 站点。
我希望这个类库(除其他外)包含一个配置 UI(有点像 Swashbuckle 如何构建一个 OpenAPI UI - 我检查了源代码并且无法完全理解那部分)。
我认为在类库中创建控制器/视图是可行的方法。
控制器自动工作(虽然,我有点担心路由冲突——如果我的类库中有一个 /foo/bar 路由,而使用这个库的项目也有一个 /foo/bar 路由怎么办?)。
但是,这些视图似乎不会自动添加。我已经尝试嵌入并遵循文件夹约定,但我仍然收到错误消息:
处理请求时发生未处理的异常。
InvalidOperationException:未找到视图“索引”。这
搜索了以下位置:/Views/Foo/Index.cshtml
/Views/Shared/Index.cshtml
这是类库的相关部分:
我需要做什么才能从类库中加载/解析/工作这些视图? (或者有没有更好的选择来做我想做的没有视图的事情?)
【问题讨论】:
标签:
c#
asp.net-mvc
asp.net-core
razor
【解决方案1】:
ApplicationParts 是答案,但我发现文档有点难以理解,所以这就是我所做的:
var assembly = typeof(FooController).Assembly;
@this.AddControllersWithViews()
.AddApplicationPart(assembly)
.AddRazorRuntimeCompilation();
@this.Configure<MvcRazorRuntimeCompilationOptions>(options =>
{ options.FileProviders.Add(new EmbeddedFileProvider(assembly)); });
对我来说关键是.AddRazorRuntimeCompilation(); 和下面一行来添加一个文件提供者。
【解决方案2】:
我按照前面的答案找到了它,并且引用的页面缺少使其工作的关键细节:
研究步骤:
-
克隆了 this page 中提到的 Microsoft Sample app
-
运行 WebAppParts 示例(.Net 核心 3.0)- 有效
-
将 WebAppParts 示例更新为 .Net 6.0 - 有效
-
创建了一个全新的 .Net 6 Web 应用程序
-
添加了 MySharedApp .Net 6 库
-
将代码片段添加到程序主要设置中并调用它而不是 AddControllersWithViews
public static void ConfigureServices(IServiceCollection services)
{
var assembly = typeof(MySharedController).Assembly;
services.AddControllersWithViews()
.AddApplicationPart(assembly)
.AddRazorRuntimeCompilation();
services.Configure<MvcRazorRuntimeCompilationOptions>(options =>
{ options.FileProviders.Add(new EmbeddedFileProvider(assembly)); });
}
-
在 _Layout.cshtml 中添加了指向 MyShared/index 的菜单超链接 - 它找不到视图
-
将示例项目与我的新项目进行比较,然后慢慢迁移设置/更改。
-
将 Microsoft.Extensions.FileProviders.Embedded NuGet 添加到库中。
-
发现在Build Action views 中,任何共享的views 都需要标记为Embedded resource。这在示例应用程序中并不明显,因为视图在示例应用程序中显示为 Content,尽管 .csproj 中有此条目
<ItemGroup>
<EmbeddedResource Include="ViewsMySharedIndex.cshtml" />
</ItemGroup>
-
在所有这些更改之后,我的 .Net 6.0 测试 Web 应用程序开始共享库的视图和控制器。
-
下面的最后一个例子是我在Program.Main() 中减少了我的应用程序代码。如果不需要,请随意删除 Auth 或 Json 行:
var assembly = typeof(AnySharedController).Assembly;
builder.Services.AddRazorPages()
.AddJsonOptions(x => x.JsonSerializerOptions.DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull)
.AddApplicationPart(assembly)
.AddRazorRuntimeCompilation()
.AddMicrosoftIdentityUI();
builder.Services.Configure<MvcRazorRuntimeCompilationOptions>(options =>
{
options.FileProviders.Add(new EmbeddedFileProvider(assembly));
});