剃刀类库(RCL)中具有静态内容的404

时间:2020-02-03 14:02:15

标签: asp.net-core .net-core asp.net-core-mvc razor-class-library

我很难在ASP.NET Core(v3.1)应用程序使用的剃刀类库(.net Core 3.1)中实现静态文件。

当尝试访问静态文件时,我只得到404-未找到。

我在Stackoverflow上遵循以下答案:https://stackoverflow.com/a/57874357/1099519

我还交叉检查了https://docs.microsoft.com/en-us/aspnet/core/razor-pages/ui-class?view=aspnetcore-3.0&tabs=visual-studio#create-an-rcl-with-static-assets上的文档。

我在库中的以下位置放置了一个CSS文件: wwwroot\css\Base.css,我测试了以下路径:https://localhost:44300/_content/OurIt.Cockpit/css/Base.css,其结果为404未找到。

我已经检查过的内容:

  • 任何具有RCL内的视图的控制器都可以浏览并且可以正常工作(将呈现的HTML代码提供给浏览器)
  • Web应用程序中有app.UseStaticFiles();
  • Web应用程序中有webBuilder.UseStaticWebAssets();
  • 正确的外壳。
  • wwwroot\css\Base.css构建操作设置为内容
  • RCL项目定义了以下sdk:<Project Sdk="Microsoft.NET.Sdk.Razor">
  • 在RCL项目中设置了以下属性:

    <PropertyGroup> <TargetFramework>netcoreapp3.1</TargetFramework> <AddRazorSupportForMvc>true</AddRazorSupportForMvc> <PropertyGroup>

我还尝试了以下答案中所述的方法:https://stackoverflow.com/a/59574845/1099519,并且尝试从https://localhost:44300/path/css/Base.css访问文件

是否有机会调试或定位问题?维护Microsoft文档:

构建RCL后,将生成一个清单,该清单描述了静态Web资产的位置。消费应用程序在运行时读取清单以消费引用的项目和程序包中的资产。

为了验证文件是否在程序集中,我试图找到该清单,但是找不到或不知道在哪里寻找(我检查了输出文件夹)。我还尝试用ILSpy打开RCL,希望找到解决该问题的方法。

有什么想法(或使用带有.NET Core 3.1静态内容的RCL的示例-我仅找到了控制器/视图的示例,但没有静态内容的示例)?

更新2020-02-05:

我在Github上创建了一个样本进行复制: https://github.com/DominikAmon/RclIssueDemo

5 个答案:

答案 0 :(得分:1)

我终于让它对我有用。我对您在https://github.com/dotnet/AspNetCore.Docs/issues/16837上创建的问题添加了评论。

我现在正在使用的.csproj的相关部分是:

<Project Sdk="Microsoft.NET.Sdk.Razor">
  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <AddRazorSupportForMvc>true</AddRazorSupportForMvc>
    <GenerateMvcApplicationPartsAssemblyAttributes>true</GenerateMvcApplicationPartsAssemblyAttributes>
    <RazorCompileOnBuild>true</RazorCompileOnBuild>
    <IncludeRazorContentInPack>false</IncludeRazorContentInPack>
    <GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest>
    <EnableDefaultRazorGenerateItems>true</EnableDefaultRazorGenerateItems>
  </PropertyGroup>

 <ItemGroup>
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
    <PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="2.1.1" />
    <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.1.1" />
  </ItemGroup>

  <PropertyGroup>
    <StaticWebAssetBasePath Condition="$(StaticWebAssetBasePath) == ''">/</StaticWebAssetBasePath>
  </PropertyGroup>
</Project>

也许不是上面所有这些设置都是必需的,但是由于它可以正常工作,所以我不想过多地触摸它-如果可以,请不要触摸:-)

现在,这里还有其他问题:

  • 因为我想在本地测试我的NuGet程序包,所以我想先将程序包推送到本地存储库文件夹,以便可以从测试应用程序中使用它们。但是,没有任何文档证明dotnet nuget也可以推送到本地目录,因此我想我必须使用独立的nuget.exe来实现这一点。好吧,显然it is not a good idea to use nuget.exe with RCL libraries。相反,您可以使用:
dotnet nuget push .\bin\Release\DynamicVML.1.0.32.nupkg -s c:\Projects\nuget

(请注意,-s选项在documentation中被描述为server URL,但实际上它可以是本地文件夹,对此没有说明)

  • 有太多过时的文章,而StackOverflow的答案可能会使您陷入错误的道路。我发生的事情是,在某个时刻我试图遵循tutorials differentsources,但事实证明该版本在.NET Core 3.1中已经过时了。我最终弄乱了我的项目文件,忘了撤消所做的某些更改。要使其全部正常工作,请确保:

  • 视图/ .cshtml文件必须设置为“ Build Action:Content”;

  • 静态文件/ js文件必须设置为“ Build Action:Content”;

现在,进入消费者应用程序部分:

  • 我不必像以前那样在Program.cs中添加webBuilder.UseStaticWebAssets();。所以我的CreateHostBuilder看起来像这样:
public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

我不必添加过时的教程中描述的任何FileProvider功能。我的ConfigureServices就像这样干净:

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();

    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseInMemoryDatabase("BookAuthors"));
}

而我的配置只是基线之一:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
        app.UseHsts();
    }
    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
    });
}

使用上述设置,一切正常。我可以包含来自RCL库的js文件,即使这些文件实际上不在消费者项目wwwroot 中也存在(我知道当前文档中已经记录了这些文件,但是在某些时候,我试图调试该文件。通过添加UseDirectoryBrowser to my configure 并检查提供的文件夹的内容来解决此问题-这不起作用,RCL中的静态文件将不会显示。)

此外,还有其他类似问题的注意事项:使用以上设置(更具体而言,由于最后一个配置块),我可以使用/中的静态文件。我没有使用/_content/LibraryName/...路径。在我的RCL中,我具有以下结构

- wwwroot
---- lib
------- myFolder
---------- myScript.js

在消费者应用程序中,我只是使用

来使用.js文件
@section Scripts {
    <script src="~/lib/myFolder/myScript.js"></script>
}

...并且有效!

答案 1 :(得分:1)

我查看了您的github示例并进行了修复。 我删除了RclDemo.Library.csproj中的两个包引用。 不知道您的整个项目是否需要这些,但是至少您可以找出是否需要它们,或者是否需要为其配置一些东西。

代码:


    <Project Sdk="Microsoft.NET.Sdk.Razor">
        <PropertyGroup>
            <TargetFramework>netcoreapp3.1</TargetFramework>
            <AddRazorSupportForMvc>true</AddRazorSupportForMvc>
        </PropertyGroup>
        <ItemGroup>
            <!--<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
            <PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="3.1.1" />-->
            <FrameworkReference Include="Microsoft.AspNetCore.App" />
        </ItemGroup>
    </Project>

答案 2 :(得分:0)

如果从RclDemo.Library项目中删除对Microsoft.AspNet.Core的引用,则一切都会按预期进行。这是应从项目文件中删除的行:

<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />

如果创建新的.NET Core 3.x应用程序,则不会包含此引用,因为它现在已作为Microsoft.AspNetCore.App框架引用的一部分包含在内。静态文件在.NET Core 2.2 Razor类库中的工作方式有所不同,我认为您对Microsoft.AspNetCore.Mvc v2.2.0库的包含是令人毛骨悚然的事情。曾经有其他配置可以在RCL中包含静态文件。

肖恩

答案 3 :(得分:0)

我关注这篇文章,并且效果很好。 https://dev.to/j_sakamoto/how-to-deal-with-the-http-404-content-foo-bar-css-not-found-when-using-razor-component-package-on-asp-net-core-blazor-app-aai

在Program.cs中,添加StaticWebAssetsLoader以包括静态文件,并能够将Rsor库类中的CSS和javascript加载

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                    webBuilder.ConfigureAppConfiguration((ctx, cb) =>
                    {
                        StaticWebAssetsLoader.UseStaticWebAssets(
                          ctx.HostingEnvironment,
                          ctx.Configuration);
                    });
                });

答案 4 :(得分:0)

我使用的是普通 Blazor 服务器模板,其中包含对我的 RCL 的项目引用。一切正常,无需任何额外代码。

我的问题是在我添加 Nuget 包属性后出现的。包 ID 与程序集名称不同。

在这种模式中:

_content/{LIBRARY NAME}/ 程序集名称 = 库名称。

添加 Nuget 属性后 PackageId = 库名称

希望这对其他人有帮助。