1. 程式人生 > >從ASP.Net Core Web Api模板中移除MVC Razor依賴項

從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/

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連結。