日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Razor Page Library:开发独立通用RPL(内嵌wwwroot资源文件夹)

發(fā)布時(shí)間:2023/12/4 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Razor Page Library:开发独立通用RPL(内嵌wwwroot资源文件夹) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Demo路徑:https://github.com/yanshengjie/RPL.Demo

1. Introduction

Razor Page Library 是ASP.NET Core 2.1引入的新類庫項(xiàng)目,屬于新特性之一,用于創(chuàng)建通用頁面公用類庫。也就意味著可以將多個(gè)Web項(xiàng)目中通用的Web頁面提取出來,封裝成RPL,以進(jìn)行代碼重用。
官方文檔Create reusable UI using the Razor Class Library project in ASP.NET Core中,僅簡(jiǎn)單介紹了如何創(chuàng)建RPL,但要想開發(fā)出一個(gè)獨(dú)立通用的RPL遠(yuǎn)遠(yuǎn)沒有那么簡(jiǎn)單,容我娓娓道來。

2. Hello RPL

老規(guī)矩,從Hello World 開始,我們創(chuàng)建一個(gè)Demo項(xiàng)目。
記住開始之前請(qǐng)確認(rèn)已安裝.NET Core 2.1 SDK!!!
我們這次使用命令行來創(chuàng)建項(xiàng)目:

>dotnet --version2.1.300>dotnet new razorclasslib --name RPL.CommonUI 已成功創(chuàng)建模板“Razor Class Library”。正在處理創(chuàng)建后操作...正在 RPL.CommonUI\RPL.CommonUI.csproj 上運(yùn)行 "dotnet restore"...正在還原 F:\Coding\Demo\RPL.CommonUI\RPL.CommonUI.csproj 的包...正在生成 MSBuild 文件 F:\Coding\Demo\RPL.CommonUI\obj\RPL.CommonUI.csproj.nuge t.g.props。正在生成 MSBuild 文件 F:\Coding\Demo\RPL.CommonUI\obj\RPL.CommonUI.csproj.nuge t.g.targets。 ?F:\Coding\Demo\RPL.CommonUI\RPL.CommonUI.csproj 的還原在 1.34 sec 內(nèi)完成。還原成功。 >dotnet new mvc --name RPL.Web 已成功創(chuàng)建模板“ASP.NET Core Web App (Model-View-Controller)”。 此模板包含非 Microsoft 的各方的技術(shù),有關(guān)詳細(xì)信息,請(qǐng)參閱 https://aka.ms/aspnetc ore-template-3pn-210。正在處理創(chuàng)建后操作...正在 RPL.Web\RPL.Web.csproj 上運(yùn)行 "dotnet restore"...正在還原 F:\Coding\Demo\RPL.Web\RPL.Web.csproj 的包...正在生成 MSBuild 文件 F:\Coding\Demo\RPL.Web\obj\RPL.Web.csproj.nuget.g.props 。正在生成 MSBuild 文件 F:\Coding\Demo\RPL.Web\obj\RPL.Web.csproj.nuget.g.target s。 ?F:\Coding\Demo\RPL.Web\RPL.Web.csproj 的還原在 2 sec 內(nèi)完成。還原成功。 >dotnet new sln --name RPL.Demo 已成功創(chuàng)建模板“Solution File”。 >dotnet sln RPL.Demo.sln add RPL.CommonUI/RPL.CommonUI.csproj 已將項(xiàng)目“RPL.CommonUI\RPL.CommonUI.csproj”添加到解決方案中。 >dotnet sln RPL.Demo.sln add RPL.Web/RPL.Web.csproj 已將項(xiàng)目“RPL.Web\RPL.Web.csproj”添加到解決方案中。

創(chuàng)建完畢后,雙擊RPL.Demo.sln打開解決方案,如下圖:

  • 修改Page1.cshtml,body內(nèi)添加<h1>This is from CommonUI.Page1</h1>

  • RPL.Web添加引用項(xiàng)目【RPL.CommonUI】

  • 設(shè)置RPL為啟動(dòng)項(xiàng)目。

  • CTRL+F5運(yùn)行。

  • 我們觀察到RPL.CommonUI中預(yù)置了一個(gè)Razor Page,因?yàn)镽azor Page是基于文件系統(tǒng)路由,所以直接https://localhost:<port>/myfeature/page1即可訪問。

    到這一步,我們就可以篤定RPL正確生效。

    3. Keep Going

    以上只是簡(jiǎn)單的HTML頁面,如果要想加以潤(rùn)色,就需要寫CSS來處理。
    兩種處理方式:

  • 使用內(nèi)聯(lián)樣式

  • 引用外部樣式文件

  • 內(nèi)聯(lián)樣式,很簡(jiǎn)單,就不加以贅述。
    我們來定義樣式文件來處理。仿照RPL.Web項(xiàng)目,創(chuàng)建一個(gè)wwwroot根目錄,然后再添加一個(gè)css文件夾,再添加一個(gè)demo.css的樣式文件。

    h1 { ? ?color: red; }

    然后將demo.css引用添加到page1.cshtml中。

    <head><meta name="viewport" content="width=device-width" /><link rel="stylesheet" href="~/css/demo.css" /><title>Page1</title></head>

    CTRL+F5重新運(yùn)行,運(yùn)行結(jié)果如下圖:

    可以清晰的看到,定義的樣式并未生效。從瀏覽器F12 Developer Tool中可以清晰的看到,無法請(qǐng)求demo.css樣式文件。
    到這里,也就拋出了本文所要解決的問題:如何開發(fā)獨(dú)立通用的RPL?
    如果RPL中無法引用項(xiàng)目中定義一些靜態(tài)資源文件(CSS、JS、Image等),那RPL將無法有效的組織View。

    4. Analyze

    要想訪問RPL中的靜態(tài)資源文件,首先我們要弄明白.NET Core Web項(xiàng)目中wwwroot文件夾的資源是如何訪問的。
    這一切得從應(yīng)用程序啟動(dòng)說起,為了方便查閱,使用Code Map將相關(guān)代碼顯示如下:

    從中可以看出在構(gòu)建WebHost的業(yè)務(wù)邏輯中會(huì)去初始化IHostingEnvironment對(duì)象。該對(duì)象主要用來描述應(yīng)用程序運(yùn)行的web宿主環(huán)境的相關(guān)信息,主要包含以下幾個(gè)屬性:

    string EnvironmentName { get; set; }string ApplicationName { get; set; }string WebRootPath { get; set; } IFileProvider WebRootFileProvider { get; set; }string ContentRootPath { get; set; } IFileProvider ContentRootFileProvider { get; set; }

    從上圖的注釋代碼中可以看到,其初始化邏輯正是去指定WebRootPath和WebRootFileProvider。
    如果我們?cè)趹?yīng)用程序未手動(dòng)通過webHostBuilder.UseWebRoot("your web root path");指定自定義的Web Root路徑,那么將會(huì)默認(rèn)指定為wwwroot文件夾。
    同時(shí)注意下面這段代碼:

    hostingEnvironment.WebRootFileProvider = newPhysicalFileProvider(hostingEnvironment.WebRootPath);

    其指定的IFileProvider的類型為PhysicalFileProvider。
    到這里,是不是就豁然開朗了,Web 應(yīng)用啟動(dòng)時(shí),指定的WebRootFileProvider僅僅映射了Web應(yīng)用的wwwroot目錄,自然是訪問不了我們RPL項(xiàng)目指定的wwwroot目錄啊。

    到這里,其實(shí)我們離問題就很近了。但是只要指定了WebRootFileProvider就可以訪問WebRoot目錄的資源了嗎?并不是。

    我們知道,ASP.NET Core是通過由一系列中間件組裝而成的請(qǐng)求管道來處理請(qǐng)求的。不管是View視圖也好,還是靜態(tài)資源文件也好,都是通過Http Request來請(qǐng)求的。HTTP Request流入請(qǐng)求管道后,根據(jù)請(qǐng)求類型,不同的中間件負(fù)責(zé)處理不同的請(qǐng)求。那對(duì)于靜態(tài)資源文件,ASP.NET Core中是借助StaticFileMiddleware中間件來處理的。這也就是為什么在啟動(dòng)類Startup的Configure方法中需要指定app.UseStaticFiles();來啟用StaticFileMiddleware中間件。

    在ASP.NET Core 官方文檔中Static files in ASP.NET Core,介紹了如何訪問自定義目錄的靜態(tài)資源文件。

    如果需要訪問自定義路徑目錄的資源,需要添加類似以下代碼:

    app.UseStaticFiles(new StaticFileOptions{FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "MyStaticFiles")),RequestPath = "/StaticFiles"});

    但這似乎并不能滿足我們的需求。Why?看標(biāo)題,開發(fā)獨(dú)立通用的RPL。怎么理解獨(dú)立通用?也就意味著RPL中的資源文件最好能夠通過程序集打包。這樣才能完全獨(dú)立。否則,在發(fā)布RPL時(shí),還需要輸出靜態(tài)資源文件,顯然增加了使用的難度。而如何將資源文件打包進(jìn)程序集呢?——內(nèi)嵌資源。

    5. Embedded Resource

    一個(gè)程序集主要由兩種類型的文件構(gòu)成,它們分別是承載IL代碼的托管模塊文件和編譯時(shí)內(nèi)嵌的資源文件。那在.NET Core中如何定義內(nèi)嵌資源呢?

  • 編輯RPL.CommonUI.csproj文件,添加wwwroot為內(nèi)嵌資源。

    ?<ItemGroup><EmbeddedResource Include="wwwroot\**\*" /></ItemGroup>
  • 添加GenerateEmbeddedFilesManifest節(jié)點(diǎn),指定生成內(nèi)嵌資源清單。

    <GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest>
  • 添加Microsoft.Extensions.FileProviders.EmbeddedNuget包引用。

  • 修改完后的RPL.CommonUI.csproj,如下所示:

    <Project Sdk="Microsoft.NET.Sdk.Razor"><PropertyGroup><TargetFramework>netstandard2.0</TargetFramework><GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest></PropertyGroup><ItemGroup><PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.1.0" /><PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="2.1.0" /></ItemGroup><ItemGroup><EmbeddedResource Include="wwwroot\**\*" /></ItemGroup></Project>

    我們用ildasm.exe反編譯RPL.CommonUI.dll,查看下其程序集清單:

    從圖中可以看出內(nèi)嵌的demo.css文件,是以{程序集名稱}.{文件路徑}命名的。

    那內(nèi)嵌資源如何訪問呢?可以借助EmbeddedFileProvider,我們仿照上面的例子,在Startup.cs的Configure方法中添加以下代碼:

    app.UseStaticFiles();var dllPath = Path.Join(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "RPL.CommonUI.dll"); app.UseStaticFiles(new StaticFileOptions {FileProvider = new ManifestEmbeddedFileProvider(Assembly.LoadFrom(dllPath), "wwwroot") });

    CTRL+F5,運(yùn)行。Perfect!

    當(dāng)然這也不是最好的解決方案,因?yàn)槟憧隙ú幌胨姓{(diào)用這個(gè)RPL的地方,添加這么幾句代碼,因?yàn)檫@段代碼有很強(qiáng)的侵入性,且不可隔離變化。

    5. Final Solution

    • 編輯RPL.CommonUI.csproj文件,添加wwwroot為內(nèi)嵌資源。

      ?<ItemGroup><EmbeddedResource Include="wwwroot\**\*" /></ItemGroup>
    • 添加GenerateEmbeddedFilesManifest節(jié)點(diǎn),指定生成內(nèi)嵌資源清單。

      <GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest>
    • 添加Microsoft.AspNetCore.StaticFiles和Microsoft.Extensions.FileProviders.EmbeddedNuget包引用。

    修改完后的RPL.CommonUI.csproj,如下所示:

    <Project Sdk="Microsoft.NET.Sdk.Razor"><PropertyGroup><TargetFramework>netstandard2.0</TargetFramework><GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest></PropertyGroup><ItemGroup><PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.1.0" /><PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.1.0" /><PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="2.1.0" /></ItemGroup><ItemGroup><EmbeddedResource Include="wwwroot\**\*" /></ItemGroup></Project>
    • 接下來添加CommonUIConfigureOptions.cs,定義如下:

    • 然后添加CommonUIServiceCollectionExtensions.cs,代碼如下:

    • 修改RPL.Web啟動(dòng)類startup.cs,在services.AddMvc()之前添加services.AddCommonUI();即可。

    • CTRL+F5重新運(yùn)行,我們發(fā)現(xiàn)H1被成功設(shè)置為紅色,檢查發(fā)現(xiàn)demo.css也能正確被請(qǐng)求,檢查network也可以看到其Request URL為:https://localhost:44379/css/demo.css

  • Static files in ASP.NET Core

  • File Providers in ASP.NET Core

  • ManifestEmbeddedFileProvider Class

  • Make it easier to use static assets that are part of a RCL project

  • .NET Core的文件系統(tǒng)[4]:由EmbeddedFileProvider構(gòu)建的內(nèi)嵌(資源)文件系統(tǒng)

  • 相關(guān)文章:?

    • 用ASP.NET Core 2.1 建立規(guī)范的 REST API -- HATEOAS

    • 在ASP.NET Core中使用brotli壓縮

    • ASP.NET Core2.1 你不得不了解的GDPR

    • .NET Core 2.1改進(jìn)了性能,并提供了新的部署選項(xiàng)

    • Entity Framework Core 2.1帶來更好的SQL語句生成方案

    原文地址: https://www.cnblogs.com/sheng-jie/p/9165547.html


    .NET社區(qū)新聞,深度好文,歡迎訪問公眾號(hào)文章匯總 http://www.csharpkit.com

    總結(jié)

    以上是生活随笔為你收集整理的Razor Page Library:开发独立通用RPL(内嵌wwwroot资源文件夹)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。