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

本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM