.Net Core路由处理的知识点与方法总结

 更新时间:2021年9月22日 09:59  点击:2240

前言

  用户请求接口路由,应用返回处理结果。应用中如何匹配请求的数据呢?为何能如此精确的找到对应的处理方法?今天就谈谈这个路由。路由负责匹配传入的HTTP请求,将这些请求发送到可以执行的终结点。终结点在应用中进行定义并且在应用启动的时候进行配置,也就是在中间件中进行处理。

路由基础知识

  在项目新建的时候都会自动生成路由相关代码。在Startup.Configure中的中间件管道注册的。主要涉及到的则是UseRouting和UseEndpoints中间件。

    UseRouting向中间件添加路由匹配。此中间件还会查看应用中定义的终结点集。也就是把应用中的路由统统注册到中间件管道,方便请求的时候进行匹配。

    UseEndpoints向中间件添加终结点执行。会运行相关联的委托。简单将就是路由匹配之后的处理事件运行。

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapGet("/", async context =>
                {
                    await context.Response.WriteAsync("Hello World!");
                });
            });
        }

  例如上面的代码就是HTPP GET 请求并且Url是/的时候需要执行的委托、如果这里的请求不是Get请求或者不是"/",那么没有路由匹配,则会返回404。同时指定匹配模式的还有MapDelete、MapMethods、MapPost、MapPut、Map等。

终结点

  上面讲的MapGet或者未用到MapPost等就是用于定义终结点的。它们都包含有两个参数,一个是用于Url匹配的,另外一个就是需要执行的委托。这里在不一样的应用中都采用了不同的终结点定义方法

  • 用于 Razor Pages 的 MapRazorPages
  • 用于控制器的 MapControllers
  • 用于 SignalR 的 MapHub
  • 用于 gRPC 的 MapGrpcService

  那么我们如果需要使用到了授权模块将如何处理呢,终结点也有相对应的处理方式。下面就展示将授权中间件和路由一起使用,MapHealthChecks添加运行状况检查终结点。后面跟着的RequireAuthorization则是将授权策略添加到端点。

           app.UseRouting();

            app.UseAuthentication();
            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapHealthChecks("/healthz").RequireAuthorization();
                endpoints.MapGet("/", async context =>
                {
                    await context.Response.WriteAsync("Hello World!");
                });
            });

  而且我们看中间的使用顺序,UseAuthentication、UseAuthorization是穿插在UseRouting和UseEndpoints中间的,如此写法则是为了授权策略能在UseRouting中查找终结点,但是能在UseEndpoints发送到终结点执行之前应用所选择的授权策略

终结点元数据

  上面的示例展示了运行状况检查终结点附加了授权策略。添加的授权策略是额外数据,也就是终结点元数据。

  • 可以通过路由感知中间件来处理元数据。
  • 元数据可以是任意的 .NET 类型。

  上面提到元数据可以是人意的.NET类型,那么具体到底是什么呢?元数据如何使用呢?

         // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            app.Use(next => context =>
            {
                var endpoint = context.GetEndpoint();
                if (endpoint?.Metadata.GetMetadata<AuditPolicyAttribute>()?.NeedsAudit ==true)
                {
                    Console.WriteLine("开始处理事务逻辑");
                    Console.WriteLine($"ACCESS TO SENSITIVE DATA AT: {DateTime.UtcNow}");
                }
                return next(context);
            });

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapGet("/", async context =>
                {
                    await context.Response.WriteAsync("Hello world!");
                });

                // Using metadata to configure the audit policy.
                endpoints.MapGet("/sensitive", async context =>
                {
                    await context.Response.WriteAsync($"sensitive data{DateTime.UtcNow}");
                })
                .WithMetadata(new AuditPolicyAttribute(needsAudit: true));
            });
        }
    }

    public class AuditPolicyAttribute : Attribute
    {
        public AuditPolicyAttribute(bool needsAudit)
        {
            NeedsAudit = needsAudit;
        }

        public bool NeedsAudit { get; }
    }

  看上面的示例中,在终结点绑定"/sensitive"的时候会附加元数据WithMetadata。当访问“/”的时候会输出"Hello world!"。但是在app.Use中并不会执行输出"处理事务逻辑",因为并没有匹配的元数据。但是当执行"/sensitive"的时候就会输出Console.WriteLine("开始处理事务逻辑");。因为在终结点定义的时候添加了元数据。元数据可以是人意.NET类型。上面的元数据也是我们自定义Class。

比较终端中间件和路由

  上面我们使用app.Use来检测匹配元数据,如果匹配成功我们就执行对应的操作。我们称之为终端中间件,为什么是终端中间件呢,因为这里会停止搜索执行匹配和操作、最后返回。

  那么相比较下终端中间件和路由有什么区别呢?

这两种方法都允许终止处理管道:终端中间件允许在管道中的任意位置放置中间件:

  • 中间件通过返回而不是调用 next 来终止管道。
  • 终结点始终是终端。

终端中间件允许在管道中的任意位置放置中间件:

  • 终结点在 UseEndpoints 位置执行。

终端中间件允许任意代码确定中间件匹配的时间:

  • 自定义路由匹配代码可能比较复杂,且难以正确编写。
  • 路由为典型应用提供了简单的解决方案。
  • 大多数应用不需要自定义路由匹配代码。

带有中间件的终结点接口,如 UseAuthorization 和 UseCors。

  • 通过 UseAuthorization 或 UseCors 使用终端中间件需要与授权系统进行手动交互

设置传统路由

  上面我们知道了通过UseRouting向中间件添加路由匹配,然后通过UseEndpoints定义终结点去执行匹配委托。那么在MVC模式中如何设置呢?我们看看传统路由的设置方法。

         app.UseEndpoints(endpoints =>
            {
                app.UseEndpoints(endpoints =>
                {
                    endpoints.MapControllerRoute(
                        name: "default",
                        pattern: "{controller=Home}/{action=Index}/{id?}");
                });
            });

  上面我们设置传统路由的时候采用的是endpoints.MapControllerRoute();,其中附带有两个参数,一个是名称default,第二个则是路由模板。我们看路由模板{controller=Home}/{action=Index}/{id?},那么在匹配Url路径的时候,例如执行路径 WeatherForecast/Index/5。那么则会匹配控制器为WeatherForecast,其中方法是Index并且参数是int类型的一个处理方法。

REST Api 的属性路由

  上面讲的是传统路由设置,那么对于Api项目的路由设置是如何的呢?REST Api 应使用属性路由将应用功能建模为一组资源。我们看下示例代码

     // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }

  在上面的代码中使用MapControllers调用。映射属性路由。我们看在使用的时候属性路由的使用方式。

Route[]

      下面的示例中我们采用的是Route[]的方式,它既可单独作用域控制器也可单独作用域action。也可同时使用。

  [ApiController]
    [Route("[controller]")]
    public class WeatherForecastController : ControllerBase
    {

        [Route("Index")]
        public string Index(int? id)
        {
            return "Test";
        }
    }

    [ApiController]
    [Route("[controller]/[action]")]
    public class WeatherForecastController : ControllerBase
    {
        public string Index(int? id)
        {
            return "Test";
        }
    }

    [ApiController]
    public class WeatherForecastController : ControllerBase
    {
        [Route("[controller]/Index")]
        public string Index(int? id)
        {
            return "Test";
        }
    }

Http[Verb]

      采用Http[Verb]的方式那就仅仅能作用在action上了。比如下面的就直接在Index上方写[HttpGet

("[controller]/Index")],其他就是HttpPost、HttpDelete等等操作
   [ApiController]
    public class WeatherForecastController : ControllerBase
    {
        [HttpGet("[controller]/Index")]
        public string Index(int? id)
        {
            return "Test";
        }
    }

Route[]和Http[Verb]混合使用

      有时在实际运用中也可以采取两种方式混合使用的,例如下面的示例在控制器采用Route[],在action采用Http[Verb]。因为一般定义Api的时候我们不仅要标注action名称,我们还需要知道action的请求方式。

  [ApiController]
    [Route("[controller]")]
    public class WeatherForecastController : ControllerBase
    {

        [HttpGet("Index")]
        public string Index(int? id)
        {
            return "Test";
        }
    }

总结

到此这篇关于.Net Core路由处理的文章就介绍到这了,更多相关.Net Core路由处理内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!

[!--infotagslink--]

相关文章

  • ASP.NET购物车实现过程详解

    这篇文章主要为大家详细介绍了ASP.NET购物车的实现过程,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-22
  • vue 实现动态路由的方法

    这篇文章主要介绍了vue 实现动态路由的方法,文中示例代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以了解下...2020-07-06
  • .NET Core下使用Kafka的方法步骤

    这篇文章主要介绍了.NET Core下使用Kafka的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-09-22
  • 在ASP.NET 2.0中操作数据之七十二:调试存储过程

    在开发过程中,使用Visual Studio的断点调试功能可以很方便帮我们调试发现程序存在的错误,同样Visual Studio也支持对SQL Server里面的存储过程进行调试,下面就让我们看看具体的调试方法。...2021-09-22
  • Win10 IIS 安装.net 4.5的方法

    这篇文章主要介绍了Win10 IIS 安装及.net 4.5及Win10安装IIS并配置ASP.NET 4.0的方法,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下...2021-09-22
  • 详解.NET Core 3.0 里新的JSON API

    这篇文章主要介绍了详解.NET Core 3.0 里新的JSON API,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-09-22
  • .net数据库操作框架SqlSugar的简单入门

    这篇文章主要介绍了.net数据库操作框架SqlSugar的简单入门,帮助大家更好的理解和学习使用.net技术,感兴趣的朋友可以了解下...2021-09-22
  • ASP.NET Core根据环境变量支持多个 appsettings.json配置文件

    这篇文章主要介绍了ASP.NET Core根据环境变量支持多个 appsettings.json配置文件,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-09-22
  • 记一次EFCore类型转换错误及解决方案

    这篇文章主要介绍了记一次EFCore类型转换错误及解决方案,帮助大家更好的理解和学习使用asp.net core,感兴趣的朋友可以了解下...2021-09-22
  • 解决vue动态路由异步加载import组件,加载不到module的问题

    这篇文章主要介绍了解决vue动态路由异步加载import组件,加载不到module的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-27
  • 解决vue-router路由拦截造成死循环问题

    这篇文章主要介绍了解决vue-router路由拦截造成死循环问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-05
  • vue.js Router中嵌套路由的实用示例

    这篇文章主要给大家介绍了关于vue.js Router中嵌套路由的相关资料,所谓嵌套路由就是路由里面嵌套他的子路由,文章通过示例代码介绍的非常详细,需要的朋友可以参考下...2021-06-27
  • vue router路由参数刷新消失问题的解决方法

    这篇文章主要介绍了vue-router路由参数刷新消失的问题...2017-06-24
  • 详解ASP.NET Core 中基于工厂的中间件激活的实现方法

    这篇文章主要介绍了ASP.NET Core 中基于工厂的中间件激活的实现方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-09-22
  • vue-router为激活的路由设置样式操作

    这篇文章主要介绍了vue-router为激活的路由设置样式操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-18
  • C#使用Ado.Net更新和添加数据到Excel表格的方法

    这篇文章主要介绍了C#使用Ado.Net更新和添加数据到Excel表格的方法,较为详细的分析了OLEDB的原理与使用技巧,可实现较为方便的操作Excel数据,需要的朋友可以参考下...2020-06-25
  • .NET C#利用ZXing生成、识别二维码/条形码

    ZXing是一个开放源码的,用Java实现的多种格式的1D/2D条码图像处理库,它包含了联系到其他语言的端口。这篇文章主要给大家介绍了.NET C#利用ZXing生成、识别二维码/条形码的方法,文中给出了详细的示例代码,有需要的朋友们可以参考借鉴。...2020-06-25
  • Vue鼠标滚轮滚动切换路由效果的实现方法

    这篇文章主要介绍了Vue鼠标滚轮滚动切换路由效果的实现方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-08-04
  • asp.net通过消息队列处理高并发请求(以抢小米手机为例)

    这篇文章主要介绍了asp.net通过消息队列处理高并发请求(以抢小米手机为例),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-09-22
  • 关于springboot中nacos动态路由的配置

    这篇文章主要介绍了springboot中nacos动态路由的配置方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-11