【问题标题】:Embedded Stylesheet in external assembly for asp.net Core 1.1asp.net Core 1.1 外部程序集中的嵌入式样式表
【发布时间】:2017-06-09 20:39:08
【问题描述】:

我正在使用 VS.2017 Community Edition15.2 更新 (26430.12),在我的解决方案中我有一个主要的 ASP.NET Core 1.1 Web 应用程序和一个 单独的程序集,它是一个 .NET Core 类库,我已经对其进行了装配,因此它是作为类库的 Web SDK,并且我从中向主 Web 应用程序提供视图组件。效果很好。

但是,我刚刚添加了几个部分视图(可能稍后会添加视图组件),但是这两个尤其需要包含样式表 (CSS) 文件。因为我希望一切都像可视组件一样自包含,所以我创建了一个 wwwroot\css 文件夹,并将我的 CSS 放入其中并使其成为嵌入式资源。

问题是......在我的主 Web 应用程序中,如果样式表嵌入在外部程序集中,我该如何在 ASP.NET Core _Layout 文件中流式传输该样式表?

【问题讨论】:

    标签: asp.net-core asp.net-core-mvc embedded-resource


    【解决方案1】:

    嗯,到目前为止,对我来说,这个 .NET Core 的东西让我的生活变得复杂而不是让它变得更容易。无论如何,我设法让 CSS 文件驻留在同一个外部程序集中,其中(外部)视图组件嵌入在我的 _Layout 中。

    一方面,我在主 Web 应用程序的 SampleAPI API 控制器 中添加了一个新的 API 方法。此 API 方法检索外部程序集中的嵌入资源并获取其流。

    让我们假设嵌入需要自定义 CSS 的视图组件的外部程序集的完整命名空间有一个 命名空间 ExternalAssembly,我在那里定义了我的组件及其 CSS文件。为了清楚起见,我省略了完整视图组件。

    ExternalAssembly.proj
         css\
            my-view-component.css
         ViewComponents\
            MyViewComponent.cs
         Views\
            Shared\
               Components\
                  MyViewComponent\
                      Default.cshtml
    

    Default.cshtml 文件和 CSS 文件在项目中被标记为嵌入式资源

    API 控制器上的 API 方法如下所示,我的应用程序是一个 ASP.NET Core 1.1 MVC,但也有一个 API。 API 方法负责将 CSS 文件作为流返回以在您的布局页面中使用:

    [HttpGet("cssMyViewComponent")]
    public IActionResult GetCss(string id) {
        var stream = typeof(ExternalAssembly.ViewComponents.MyViewComponent)
     .GetTypeInfo().Assembly
     .GetManifestResourceStream("ExternalAssembly.css.my-view-component.css");
    }
    

    确保获取嵌入资源的实际名称,注意 css 文件夹名称是该资源完整命名空间的一部分。如果不确定,您可以使用 ILDASM 打开外部程序集并查找资源名称。

    最后,我在 _Layout.cshtml 中引用 CSS,使用 API 方法的名称和为其定义的路由:

    <link rel="stylesheet" href="~/api/SampleAPI/cssMyViewComponent" />
    

    【讨论】:

      【解决方案2】:

      基于docs ,我认为理论上您可以像这样向静态文件中间件添加嵌入式文件提供程序:

      var embeddedFiles = new EmbeddedFileProvider(
                      typeof(yourtype).GetTypeInfo().Assembly,
                      "your.assembly.name"
                  );
      
      builder.UseStaticFiles(new StaticFileOptions()
      {
          FileProvider = embeddedFiles
          //,RequestPath = new PathString("/files") // optionally use a path other than /
      });
      

      如果这种方式可行,那可能是最好的,但我自己没有尝试过,所以不能 100% 确定可行。目前在我的项目中,我刚刚添加了控制器操作,这些操作返回了我的嵌入式静态资源,您可以在我的FileManagerController 中的 css、js 和字体操作方法中看到这些资源@

      我的 FileManagerController 需要 css 和 js 以及字体,所以我有每个操作方法和一个私有帮助操作方法。它可以工作,但是当我有机会时,我会尝试另一种方式,因为它的代码会少得多。 我的资源的 url 就像 [controller]/action 所以 filemanager/css、filemanager/js、filemanager/fonts 在我的例子中。

      2017-06-09 更新:我现在使用 StaticFiles 中间件方法在我自己的项目中实现了为嵌入式静态资源提供服务。我可以确认它通常可以工作,但是如果嵌入式资源有任何问题 - 在文件夹段中找不到资源,因为 - 在文件夹段中需要更改为 _ 才能找到资源,但是 - 在文件名中是可以的。 EmbeddedFileProvider 不处理这个问题,所以我报告了一个问题 here 并在我的项目中使用 custom IFileProvider 解决了它。

      如上所述,也可以从控制器操作中提供静态资源,但 MVC 在身份验证/授权中间件之后运行,因此结果是这些中间件在处理静态文件请求时运行,这可以避免使用之前运行的静态文件中间件那。我想如果需要保护嵌入式静态资源,那么使用控制器操作将是一种方法,但我不需要它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-10
        • 2011-03-22
        • 2022-12-31
        • 2021-11-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多