• 从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/

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

  • 相关阅读:
    事务
    MySQL删除表的方式
    建立索引的原则
    对表设置引擎
    运算符
    数据库锁简介
    为什么对表设置主键
    php苹果原生apns推送接口
    华为推送
    php操作redis
  • 原文地址:https://www.cnblogs.com/runningsmallguo/p/11620464.html
Copyright © 2020-2023  润新知