從ASP.Net Core Web Api模板中移除MVC Razor依賴項
前言 :本篇文章,我將會介紹如何在不包括MVC / Razor功能和包的情況下,新增最少的依賴項到ASP.NET Core Web API專案中。
一、MVC VS WebApi
(1)在ASP.NET的早期版本中,MVC和Web API技術棧是完全分開的。 儘管它們之間共享了許多相似的概念,但實際型別卻截然不同。 這通常有點尷尬,當您意外引用錯誤的名稱空間時,通常會導致錯誤。
(2)在ASP.NET Core中,這不再是個問題:MVC和Web API已統一,其中MVC中的控制器和Web API中的控制器之間基本上沒有真正的區別。 您所有的控制器都可以充當MVC控制器,也可以充當Web API控制器,以返回格式化(例如JSON或XML)資料。
(3)話雖如此,如果您只需要使用Web API功能,那麼您可能就不需要MVC功能。 但是,當前預設模板中卻預設包含了MVC的功能。
二、預設模板
當您從Visual Studio中的模板或通過命令列建立新的MVC專案時,可以選擇建立空的ASP.NET Core專案,Web API專案還是MVC Web應用程式專案。如果您建立一個“空”專案,那麼生成的應用程式實際上是超輕量級的。 它不依賴於任何MVC構造,並且在執行時僅產生一個非常簡單的“ Hello World”響應:
另一方面,如果你選擇了“ MVC Web app”模板的話,該模板會為您提供了更“完善”的應用。 如果您選擇了身份驗證選項,除了所有MVC配置和Razor檢視模板外,它還可以包括ASP.NET Core Identity,EF Core和SQL Server整合:
如果你選擇了WebApi模板的話,會建立WebApi 應用並且包含一些必須的MVC依賴項,最簡單的版本就包含了一個ValuesController。
但是,雖然看起來很簡單,但它也添加了用於建立完整MVC應用程式所有必需依賴包,即伺服器端Razor依賴包。 這是因為它包含與整個MVC Web應用程式相同的Microsoft.AspNetCore.Mvc程式包,並在Startup.ConfigureServices中呼叫AddMvc()。如下圖所示:
AddMvc()將會向服務容器中新增一堆各種服務, 其中一些是允許您使用Web API所必需的,但其中一些(尤其是與Razor相關的服務)對於Web API而言是不必要的。
在大多數情況下,使用Microsoft.AspNetCore.Mvc包是最容易的事情,但是有時您希望儘可能地減少依賴關係,並儘可能地減輕API的負擔。 在這些場景下,您可能會發現僅專門新增應用程式所需的MVC軟體包和服務會很有用。
三、新增依賴包的正確姿勢
我們將從“空” Web應用程式模板開始,然後向其中新增Web API所需的包。您需要那些軟體包將取決於您應用程式所需的功能。 預設情況下,Empty ASP.NET Core模板包括ApplicationInsights和Microsoft.AspNetCore元資料包,因此我將其留在專案中。
在這些之上,我將新增MVC.Core包,JSON格式化程式包和CORS包:
- MVC Core軟體包添加了所有必需的MVC型別,例如ControllerBase和RouteAttribute,以及許多依賴項,例如Microsoft.AspNetCore.Mvc.Abstractions和Microsoft.AspNetCore.Authorization。
- JSON格式化程式包確保我們可以實際呈現Web API操作結果
- CORS軟體包增加了跨源資源共享(CORS)支援-這是Web API常見的要求,該Web API將託管在呼叫它們的客戶端不同的域中。
最終的.csproj檔案應如下所示:
為了方便我練習我貼出文字版的專案檔案:
<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>netcoreapp2.1</TargetFramework> </PropertyGroup> <ItemGroup> <Folder Include="wwwroot\" /> </ItemGroup> <ItemGroup> <PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.1.0" /> <PackageReference Include="Microsoft.AspNetCore" Version="2.1.0" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.1.0" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.Cors" Version="2.1.0" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.Formatters.Json" Version="2.1.0" /> </ItemGroup> </Project>
還原完軟體包後,現在我們就 可以更新Startup檔案來新增我們的WebApi服務了.
四、在 Startup.cs檔案中新增我們必須的服務
在大多數情況下,將Web API服務新增到專案中就像在ConfigureServices方法中呼叫AddMvc()一樣簡單。 但是,該方法增加了我們不需要的一些依賴項。 預設情況下,它將新增ApiExplorer,Razor檢視引擎,Razor views,TagHelpers和DataAnnotations-目前我們都沒有使用(如果後面用到了我們稍後再新增ApiExplorer和DataAnnotations都是可以的),但現在我們不需要。相反,我們只需要新增一下服務:
public void ConfigureServices(IServiceCollection services) { var builder = services.AddMvcCore(); builder.AddAuthorization(); builder.AddFormatterMappings(); builder.AddJsonFormatters(); builder.AddCors(); }
這就是我們需要的服務,好了,現在我們在新增所需要的中介軟體。
五、新增中介軟體
將MvcMiddleware新增到管道很簡單。 我們只需要用UseMvc()替換了執行“ Hello World”中介軟體就行了。但是, 請注意,我們使用的是該方法的非引數化版本,該版本沒有向該應用程式新增任何常規路由。 由於這是一個Web API,因此我將僅使用屬性路由,因此無需設定常規路由。
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { //if (env.IsDevelopment()) //{ // app.UseDeveloperExceptionPage(); //} //app.Run(async (context) => //{ // await context.Response.WriteAsync("Hello World!"); //}); loggerFactory.AddConsole(); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseMvc(); }
這些就是我們所需要的MVC配置,最後,我們再來建立一個控制器,來看看是否能正確執行。
六、新增一個 MVC控制器
以這種方式建立Web API時需要注意的一個重要點就是:您必須使用ControllerBase類作為所有Controller的父類,而不是Controller。 後者在Microsoft.AspNetCore.Mvc程式包中已經定義但是我們沒有新增。 幸運的是,它主要包含與渲染Razor有關的方法,因此這對我們來說不是問題。 ControllerBase類包含您可能會使用的所有各種StatusCodeResult幫助方法,例如下面的程式碼:
[Route("api/[controller]")] public class ValuesController:ControllerBase { // GET api/values [HttpGet] public IActionResult Get() { return Ok(new string[] { "value1", "value2" }); } }
執行結果如下:
瞧! 這就是精簡的Web API控制器,具有最小的依賴項。
七、擴充套件:AddWebApi擴充套件方法
最後梳理一下-我們的ConfigureServices方法看起來有點亂。 在這種方法中,我們可以通過建立一個擴充套件方法來減少Startup.cs類中的混亂情況,程式碼如下:
using System; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Internal; // ReSharper disable once CheckNamespace namespace Microsoft.Extensions.DependencyInjection { public static class WebApiServiceCollectionExtensions { /// <summary> /// Adds MVC services to the specified <see cref="IServiceCollection" /> for Web API. /// This is a slimmed down version of <see cref="MvcServiceCollectionExtensions.AddMvc"/> /// </summary> /// <param name="services">The <see cref="IServiceCollection" /> to add services to.</param> /// <returns>An <see cref="IMvcBuilder"/> that can be used to further configure the MVC services.</returns> public static IMvcBuilder AddWebApi(this IServiceCollection services) { if (services == null) throw new ArgumentNullException(nameof(services)); var builder = services.AddMvcCore(); builder.AddAuthorization(); builder.AddFormatterMappings(); // +10 order builder.AddJsonFormatters(); builder.AddCors(); return new MvcBuilder(builder.Services, builder.PartManager); } /// <summary> /// Adds MVC services to the specified <see cref="IServiceCollection" /> for Web API. /// This is a slimmed down version of <see cref="MvcServiceCollectionExtensions.AddMvc"/> /// </summary> /// <param name="services">The <see cref="IServiceCollection" /> to add services to.</param> /// <param name="setupAction">An <see cref="Action{MvcOptions}"/> to configure the provided <see cref="MvcOptions"/>.</param> /// <returns>An <see cref="IMvcBuilder"/> that can be used to further configure the MVC services.</returns> public static IMvcBuilder AddWebApi(this IServiceCollection services, Action<MvcOptions> setupAction) { if (services == null) throw new ArgumentNullException(nameof(services)); if (setupAction == null) throw new ArgumentNullException(nameof(setupAction)); var builder = services.AddWebApi(); builder.Services.Configure(setupAction); return builder; } } }
最後,我們可以使用此擴充套件方法來整理我們的ConfigureServices方法:
public void ConfigureServices(IServiceCollection services) { services.AddWebApi(); }
這下看起來就清爽多了。
八、總結:
這篇文章展示了當您知道不需要Razor依賴時,如何從應用程式中移除它們。 這幾乎使我們能在應用程式中使用的最小化的Web API。 我知道方法可能會有很多,但是,新增額外的功能(例如ApiExplorer)卻很容易!好了,今天就聊到這裡。幸運的是,Net Core 3.0 中已經為我們做了這些工作,如果不瞭解的可以參考我以前的文章,也可以檢視原始碼。
參考文章 :https://andrewlock.net/removing-the-mvc-razor-dependencies-from-the-web-api-template-in-asp-net-core/
作者:郭崢
出處:http://www.cnblogs.com/runningsmallguo/
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連結。