ASP.NET Core - 从类库中查看

syv*_*ven 3 c# asp.net-core asp.net-core-middleware asp.net-core-3.0

我试图使我的 asp.net 核心项目完全模块化。所以我将一些功能分组并在不同的类库中分离它们。通过这种结构,我可以通过在 asp.net 项目中添加/删除 dll 的引用来激活/停用功能。

C# 部分工作正常。像images/js/css/html这样的内容文件也建立在输出文件夹中,可以毫无问题地在html中引用。

但是我如何使用 html 文件作为我的剃刀视图?

示例类库(NoteModule):https ://i.ibb.co/tb7fbxg/so-1.png


程序.cs

public static class Program
    {
        public static void Main(string[] args)
        {
            var assembly = Assembly.GetEntryAssembly();
            var assemblyLocation = assembly.Location;
            var assemblyPath = Path.GetDirectoryName(assemblyLocation);

            var builder = Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(x => x.UseWebRoot(assemblyPath).UseStartup<Startup>());
            var build = builder.Build();
            build.Run();
        }
    }
Run Code Online (Sandbox Code Playgroud)

启动文件

public class Startup
    {
        public IConfiguration Configuration { get; }

        public Startup(IConfiguration configuration)
        {
            this.Configuration = configuration;
        }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();
            services.AddRazorPages();
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseHsts();
            }

            app.UseDefaultFiles(new DefaultFilesOptions
            {
                FileProvider = new PhysicalFileProvider(Path.Combine(env.WebRootPath, "Views")),
                RequestPath = "/Views",
            });
            app.UseStaticFiles(new StaticFileOptions
            {
                FileProvider = new PhysicalFileProvider(Path.Combine(env.WebRootPath, "Assets")),
                RequestPath = "/Assets",
            });
            app.UseStaticFiles(new StaticFileOptions
            {
                FileProvider = new PhysicalFileProvider(Path.Combine(env.WebRootPath, "Views")),
                RequestPath = "/Views",
            });

            //app.UseMiddleware<ContentMiddleware>();
            app.UseRouting();
            app.UseAuthorization();
            app.UseEndpoints(x =>
            {
                x.MapControllerRoute("default", "{controller=" + Constants.ROUTE_DEFAULT_CONTROLLER + "}/{action=" + Constants.ROUTE_DEFAULT_ACTION + "}/{id?}");
                x.MapRazorPages();
            });
        }
    }
Run Code Online (Sandbox Code Playgroud)

我尝试通过自定义中间件从文件路径将 html 数据注入响应流中。但是这样 Razor-Commands 不会被执行。

我该如何解决?有没有更简单的方法?

内容中间件.cs

    public class ContentMiddleware
    {
        private RequestDelegate Next { get; }
        private IWebHostEnvironment Environment { get; }

        public ContentMiddleware(RequestDelegate next, IWebHostEnvironment env)
        {
            this.Next = next;
            this.Environment = env;
        }

        public async Task Invoke(HttpContext context)
        {
            var route = context.Request.Path.Value.Substring(1).Replace("/", "\\");
            var contentDirectory = Path.Combine(this.Environment.WebRootPath, "Views");
            var contentPath = new FileInfo(Path.Combine(contentDirectory, $"{route}.cshtml"));

            var buffer = await File.ReadAllBytesAsync(contentPath.FullName);

            context.Response.StatusCode = (int)HttpStatusCode.OK;
            context.Response.ContentLength = buffer.Length;
            context.Response.ContentType = "text/html";

            using (var stream = context.Response.Body)
            {
                await stream.WriteAsync(buffer, default, buffer.Length);
                await stream.FlushAsync();
            }

            await this.Next(context);
        }
    }
Run Code Online (Sandbox Code Playgroud)

syv*_*ven 5

经过2天的研究,我得到了答案:

一个类库是不够的。您需要一个 Razor 类库。

或者您可以编辑您的 .csproj:

// from
<Project Sdk="Microsoft.NET.Sdk">
// to
<Project Sdk="Microsoft.NET.Sdk.Razor">
Run Code Online (Sandbox Code Playgroud)
// from
  <PropertyGroup>
    <TargetFramework>netcoreapp3.0</TargetFramework>
  </PropertyGroup>
// to
  <PropertyGroup>
    <TargetFramework>netcoreapp3.0</TargetFramework>
    <AddRazorSupportForMvc>true</AddRazorSupportForMvc>
  </PropertyGroup>
Run Code Online (Sandbox Code Playgroud)