大家好,我是张飞洪,感谢您的阅读,我会不定期和你分享学习心得,希望我的文章能成为你成长路上的垫脚石,让我们一起精进。

在本文中,我们将讨论ASP.NET Core中的新路由。我们将了解什么是接口(endpoints)路由,它是如何工作的,它在哪里使用,以及如何创建自己的路由。

本文主题:

  • 探索接口路由
  • 创建自定义接口
  • 创建更复杂的接口

名词定义:端点,即我们访问的接口或者叫API,有些地方叫EndPoint或者叫接口,其实源头的称呼应该叫端点会更贴切一些。或者你也可以直接叫EndPoint,但是先不管那么多,大概了解这个意思就可以了。

探索接口路由

要了解接口路由(End Point),您需要了解什么是端点以及什么是路由。

端点是应用程序的一部分,当路由将传入的请求映射到它时,端点就会被执行。

客户端通常从服务器请求资源。大多数情况下,客户端是一个浏览器。资源由指向特定目标的URL定义。除了网页,它也可以是一个移动应用程序,从Web API请求特定JSON数据。

另一方面,执行的端点被映射到一个特定的路由,ASP.NET Core开发人员已经熟悉这样一种路由模式:

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

如果路由或路由模式与传入请求的URL匹配,则请求将映射到该端点。

ASP.NET Core可以映射到以下端点:

  • Controllers (例如, MVC or web APIs)
  • Razor Pages
  • SignalR (and Blazor Server)
  • gRPC services
  • Health checks

    大多数端点都有非常简单的路由模式。只有MVC和Web API端点使用更复杂的模式。Razor页面的路由定义基于实际页面的文件夹和文件结构。

在ASP.NET Core 2.2中引入端点之前,路由只是运用在MVC和Web API中。Razor Pages中的隐式路由是内置的,SignalR没有路由一说。Blazor和gRPC在当时还不不知道在哪儿,健康检查最初是作为中间件组件实现的。

引入端点路由是为了将路由与实际端点分离,说得白话一点,就是让URL地址和实际执行的Action进行分离,这会让框架更加灵活,同时这意味着新的端点不需要实现自己的路由。

创建自定义接口

创建端点的最简单方法是使用lambda:

app.Map("/map", async context => {
await context.Response.WriteAsync("OK");
});

这里将/map路由映射到一个简单的端点,该端点将单词“OK”写入响应流。

关于早期.NET 6.0版本的说明

.NET 6.0之前,该映射只能在Startup.cs文件中的UseEndpoints方法中,而使用.NET 6.0和新的Minimal API方法,可以在Program.cs文件中完成映射。

另外,我们需要将Microsoft.AspNetCore.Http命名空间添加到using语句中。

还可以将特定的HTTP方法(如GET、POST、PUT和DELETE)映射到端点。以下代码显示了如何映射GET和POST方法:

app.MapGet("/mapget", async context => {
await context.Response.WriteAsync("Map GET");
});
app.MapPost("/mappost", async context => {
await context.Response.WriteAsync("Map POST");
});

我们还可以将两个或多个HTTP方法映射到一个端点:

app.MapMethods("/mapmethods",  new[] { "DELETE", "PUT" },
async context => {
await context.Response.WriteAsync("Map Methods");
});

这些端点映射很像我们在第8篇定制.NET 6.0的Middleware中间件中看到的基于lambda的中间件组件,这些管道中间件会返回结果,例如基于HTML的视图、JSON结构化数据或类似的内容。但是,端点路由是一种更灵活的输出方式,它应该会在ASP.NET Core 3.0以后的所有版本中进行使用。

在第8篇中,我们看到我们可以像这样的分支管道:

app.Map("/map", mapped => {     // ……  });

以上这种方式也会创建一个路由,但只会侦听以/map开头的URL。如果您希望有一个处理/map/{id:int?}等模式的路由引擎,来匹配/map/456而不是/map/abc,那么您应该使用前面所述的新的路由。

而那些基于lambda的端点映射,对于简单的场景非常有用。然而,由于它们是在Program.cs中定义的,如果您想使用这种方式来实现更复杂的场景,代码维护性将变得很差。

因此,我们应该尝试找到一种更结构化的方法来创建自定义端点。

创建更复杂的接口

接下来,我们将创建一个健康检查接口例子,有点类似于您在Kubernetes集群中运行应用程序时可能需要的接口,用来检测系统的健康状态:

我们从开发者的角度定义API接口,我们首先添加一个MapMyHealthChecks方法,作为IEndpointRouteBuilder对象上的一个扩展方法,它没有实现:

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

为了避免混淆,我们这儿采取和之前类似的方式添加新接口,后面我们进一步来实现一下。

我们创建一个名为MapMyHealthChecksExtensions的静态类,并在MapMyHealthCheck中放置一个扩展方法,该对象扩展IEndpointRouteBuilder接口并返回IEndpointConventionBuilder对象:

namespace RoutingSample;
public static class MapMyHealthChecksExtensions {     
public static IEndpointConventionBuilder  MapMyHealthChecks (this IEndpointRouteBuilder endpoints, string pattern = "/myhealth")     
{         
// ...     
}
}

以上只是骨架,实际的接口将被实现为一个终止的中间件,也就是说,它不调用下一个的中间件组件,并创建响应流的输出:

namespace RoutingSample;
public class MyHealthChecksMiddleware {     
private readonly ILogger _logger;     
public MyHealthChecksMiddleware (RequestDelegate next, ILogger logger)    
 {  
_logger = logger;     
}      public async Task Invoke(HttpContext context)     {         
// add some checks here...         
context.Response.StatusCode = 200;         
context.Response.ContentType = "text/plain";         
await context.Response.WriteAsync("OK");     
}
}

实际工作是在Invoke方法中完成的。目前,只演示200状态码和OK状态响应,我们可以在这里随意扩展该方法,例如检查数据库或相关服务的可用性。

接下来我们使用这个终止中间件,我们回到MapMyHealthChecks方法的框架。我们现在创建一个自己的管道,并将其映射到给定的pipeline:

var pipeline = endpoints.CreateApplicationBuilder().UseMiddleware().Build();
return endpoints.Map(pattern, pipeline).WithDisplayName("My custom health checks");

这种方法允许我们为这个新的管道添加更多的中间件。WithDisplayName扩展方法将配置的显示名称设置为接口,接下来按F5键启动程序,并在浏览器中调用https://localhost:7111/myhealth。我们将看到:



请注意,端口号可能会有所不同。我们还可以将已经存在的终止中间件组件转换为路由接口,以配置更加灵活的路由。

总结

ASP.NET Core支持请求处理并向请求提供信息的多种方法。接口路由是一种基于URL和请求的方法提供资源。

在本文,我们学习了如何使用终止中间件组件作为接口,并用将该接口映射到新的路由引擎,从而让我们的路由变得更加强大和灵活。

每个Web应用程序都需要了解系统用户,以允许或限制对特定数据的访问。在下一章中,我们将展示如何配置身份验证和识别用户。

在.NET 6.0中自定义接口路由的更多相关文章

  1. Java6.0中Comparable接口与Comparator接口详解

    Java6.0中Comparable接口与Comparator接口详解 说到现在,读者应该对Comparable接口有了大概的了解,但是为什么又要有一个Comparator接口呢?难道Java的开发者 ...

  2. Django2.0中得url路由path得用法

    Django2.0中,url得匹配规则更新了,在django1.0中,url是用正则表达式书写得,相对来说比较繁琐一些,在django2.0中进行了升级优化,改为了path from django.u ...

  3. Django2.0中URL的路由机制

    路由是关联url及其处理函数关系的过程.Django的url路由配置在settings.py文件中ROOT_URLCONF变量指定全局路由文件名称. Django的路由都写在urls.py文件中的ur ...

  4. hadoop2.6.0中自定义分割符

    最近在学习hadoop,用的hadoop2.6.0 然后在学习编写mapreduce程序时,发现默认对文件的输入是采用每行进行分割,下面来分析下改变这个分割方式的办法: 来看看默认是怎样实现的:

  5. .net6.0 中一个接口多个实现的服务注册与注入

    1.现有一个数据库操作接口 如下   它有两个数据操作实现 Sqlserver 和MySql的数据库操作实现类 现在我们需要 将这个两个类 注册到MVC中 注意这里注册的服务类型都是 IDataBas ...

  6. ASP.NET Core 3.0中使用动态控制器路由

    原文:Dynamic controller routing in ASP.NET Core 3.0 作者:Filip W 译文:https://www.cnblogs.com/lwqlun/p/114 ...

  7. Django1.0和2.0中的rest_framework的序列化组件之超链接字段的处理

    大家看到这个标题是不是有点懵逼,其实我就是想要一个这样的效果 比如我get一条书籍的数据,在一对多的字段中我们显示一个url,看起来是不是很绚! 下面我们就来实现这么一个东西 首先我们一对多字段中的一 ...

  8. IHostingEnvironment VS IHostEnvironment - .NET Core 3.0中的废弃类型

    原文: https://andrewlock.net/ihostingenvironment-vs-ihost-environment-obsolete-types-in-net-core-3/ 作者 ...

  9. 避免在ASP.NET Core 3.0中为启动类注入服务

    本篇是如何升级到ASP.NET Core 3.0系列文章的第二篇. Part 1 - 将.NET Standard 2.0类库转换为.NET Core 3.0类库 Part 2 - IHostingE ...

  10. 探索ASP.Net Core 3.0系列二:聊聊ASP.Net Core 3.0 中的Startup.cs

    原文:探索ASP.Net Core 3.0系列二:聊聊ASP.Net Core 3.0 中的Startup.cs 前言:.NET Core 3.0 SDK包含比以前版本更多的现成模板. 在本文中,我将 ...

随机推荐

  1. VMware虚拟机中Ubuntu18.04无法连接网络的有效解决办法

    对VMware虚拟机进行恢复默认网络设置 恢复虚拟网络默认设置(在断网状态下): 1)Ubuntu网络设置自动获取IP 依次单击[System Settings]–>[Network]–> ...

  2. HTTP 协议相关

    一. HTTP常见请求头 1. Host (主机和端口号) 2. Connection (连接类型) 3.Upgrade-Insecure-Requests (升级为HTTPS请求) 4. User- ...

  3. 如何像Facebook一样构建数据中心 – BGP在大规模数据中心中的应用(3)

    如何像Facebook一样构建数据中心 – BGP在大规模数据中心中的应用(3) superrace• 18-06-12 作者简介:史梦晨,曾就职于国内金牌集成商, 现就职于EANTC( 欧洲高级网络 ...

  4. Matlab:读取、写入(.txt)(.xlsx)

    写入txt a=[1,2,3;4,5,6]; save C:\Users\Administrator\Desktop\a.txt -ascii a 参考:https://blog.csdn.net/h ...

  5. pandas加速读取数据记录csv大文件处理

    def readf(file): t0 = time.time() data=pd.read_csv(file,low_memory=False,encoding='gbk' #,nrows=100 ...

  6. VScode_Keter_自用

    1.软件下载 支持win/linux/mac平台,安装有两种形式,根据个人喜好进行选择即可: 1.安装包 a.官网下载地址:https://code.visualstudio.com/ (速度慢) b ...

  7. [复现]2021DASCTF实战精英夏令营暨DASCTF July X CBCTF-PWN

    EasyHeap 想可执行的地方写入orw的shellcode,利用tcachebin的df进行劫持malloc_hook 然后调用add来触发. from pwn import * context. ...

  8. adb命令2

    1.获取手机型号指令 adb shell cat /system/build.prop | findstr "ro.product.model" 2.获取手机处理器信息 adb s ...

  9. fatal: unable to access 'https://github.com/github-eliviate/papers.git/': Failed to connect to github.com port 443 after 21107 ms: Timed out

    fatal: unable to access 'https://github.com/github-eliviate/papers.git/': Failed to connect to githu ...

  10. [SUCTF 2019]EasySQL 1

    这个题目搞了我好久,由于本人基础不扎实,试了好多方法,只发现有三种情况 Nonono.无返回结果和有返回 然后使用了新学习的堆叠注入,得到了数据库名和表名 想要查看Flag表的字段内容也查看不了 这里 ...