开始

回顾上一篇文章:dotnet core开发体验之开始MVC 里面体验了一把mvc,然后我们知道了aspnet mvc是靠Routing来驱动起来的,所以感觉需要研究一下Routing是什么鬼。

Routing简单使用体验

首先我们用命令yo aspnet创建一个新的空web项目。(Yeoman的使用自己研究,参考:https://docs.asp.net/en/latest/client-side/yeoman.html?#building-projects-with-yeoman)

创建完项目后,在project.json里面添加Routing依赖。

"dependencies": {    ..."Microsoft.AspNetCore.Routing": "1.0.0-*"},

添加完依赖后,修改Startup里面的Configure,和ConfigureServices里面添加Routing的使用依赖
修改前:

public void Configure(IApplicationBuilder app){app.Run(async (context) =>{            await context.Response.WriteAsync("Hello World!");});
}

修改后:

public void ConfigureServices(IServiceCollection services){services.AddRouting();
}public void Configure(IApplicationBuilder app){        var endpoint = new RouteHandler((c) => c.Response.WriteAsync("Hello, I am Routing!"));app.UseRouter(endpoint);
}

dotnet run 然后浏览器访问http://localhost:5000/ 显示为Hello, I am Routing! 接下来我们在http://localhost:5000/ 后面加入一些其他的东西来访问,发现其实还是一样打印Hello, I am Routing! 这让我们感觉好像并没有什么卵用的样子。不着急我们先来看看Routing是怎么运行起来的。在开始这话题之前需要先了解到什么是中间件,参考:https://docs.asp.net/en/latest/fundamentals/middleware.html

Routing的最基本运行原理

Routing的驱动入口就是基于middleware的。可以先看看 app.UseRouter(endpoint)的内部实现,参考一个扩展方法类RoutingBuilderExtensions,可以看到最后有一句代码return builder.UseMiddleware<RouterMiddleware>(router) 。这里可以很明显看到,入口在RouterMiddleware的Invoke方法。

    public async Task Invoke(HttpContext httpContext)   {            var context = new RouteContext(httpContext);context.RouteData.Routers.Add(_router);               await _router.RouteAsync(context);              if (context.Handler == null){_logger.RequestDidNotMatchRoutes();                   await _next.Invoke(httpContext);}               else{httpContext.Features[typeof(IRoutingFeature)] = new RoutingFeature(){RouteData = context.RouteData,};            await context.Handler(context.HttpContext);}}

这个入口的实现是这样的:

Invoke入口 ===>>> 实例化一个 RouteContext ===>>> 把我们传进来的 IRouter 存到 RouteContext里面的 RouteData===>>> 再执行IRouter的RouteAsync方法把RouteContext对象传进去提供给具体实现使用。===>>> 如果context.Handler没有东西,就执行下一个RequestDelegate,如果有的话就把RouteData保存起来然后执行这个RequestDelegate。

看到了这里我们已经可以明白下面这个代码运行起来的原理。

public void Configure(IApplicationBuilder app){     

   var endpoint = new RouteHandler((c) => c.Response.WriteAsync("Hello, I am Routing!"));app.UseRouter(endpoint);
}

可能还会有人不明白RouteHandler是个什么鬼,既然我们知道了代码的实现运行原理,那么肯定可以猜到RouteHandler是有实现接口IRouter的。我们可以看RouteHandler代码

    public Task RouteAsync(RouteContext context)    {context.Handler = _requestDelegate;            return TaskCache.CompletedTask;}

这里可以看到把我们的(c) => c.Response.WriteAsync("Hello, I am Routing!")赋值给context.Handler,然后由RouterMiddleware来执行我们这个事件方法。于是我们就可以在浏览器上面看到输出 Hello, I am Routing!这么一句话了。

Routing的一些使用

文章到现在,我们虽然知道了Routing运行起来的一个大概原理,但是我们一直打印出相同内容,确实也没有什么卵用呀。我们要改一下让打印内容能有点改变。这个时候可以使用到Routing提供的Route类来使用。代码修改如下:

    public void Configure(IApplicationBuilder app)    {            var endpoint = new RouteHandler((c) => c.Response.WriteAsync($"Hello, I am Routing! your item is {c.GetRouteValue("item")}"));          var resolver = app.ApplicationServices.GetRequiredService<IInlineConstraintResolver>();              var runRoute = new Route(endpoint,"{item}",resolver);app.UseRouter(runRoute);}

修改完代码后,我们再次编译运行,然后输入http://localhost:5000/ 我们发现一片空白,然后再输入http://localhost:5000/abc 发现打印出来的是Hello, I am Routing! your item is abc。然后再输入其他的 http://localhost:5000/abc/cc 发现也是一片空白。这是因为我们给路由添加的匹配是主机地址/+{item}那其他的路径都是匹配不到,那么肯定就是不会显示任何东西啦。假设我们要给一个默认值,那么可以改成这样

var runRoute = new Route(endpoint,"{item=home}",resolver);

OK,这个时候我们再输入http://localhost:5000/ 看到的就是Hello, I am Routing! your item is home。

匹配原理相对比较复杂点,想要了解的话可以参考 RouteBase的源码,然后看相关的类,看看我们设置的模板是如何解析的,然后如何和url进行匹配的。如果要要来解释完整个过程的话,这个文章肯定是不够的,所以各位可以自己了解一下。

假如要配置多个路由支持的话,可以使用RouteCollection

    public void Configure(IApplicationBuilder app)    {            var endpoint = new RouteHandler((c) => c.Response.WriteAsync($"Hello, I am Routing! your item is {c.GetRouteValue("item")}"));       var resolver = app.ApplicationServices.GetRequiredService<IInlineConstraintResolver>();             var runRoute = new Route(endpoint,"{item=home}",resolver);        var otherRoute = new Route(endpoint,"other/{item=other_home}",resolver);         var routeCollection = new RouteCollection();routeCollection.Add(runRoute);routeCollection.Add(otherRoute);app.UseRouter(routeCollection);}

修改成上面的代码后就支持两个路由,假如输入的url是 http://localhost:5000/other 那么就是使用runRoute,如果输入的是http://localhost:5000/other/myother 那么使用的就是otherRoute。

这样书写暴露了很多细节东西,我们可以用 Routing提供的RouteBuilder类来编写相同的东西。代码修改一下如下:

public void Configure(IApplicationBuilder app)    {        var endpoint = new RouteHandler((c) => c.Response.WriteAsync($"Hello, I am Routing! your item is {c.GetRouteValue("item")}"));        var routeBuilder = new RouteBuilder(app){DefaultHandler = endpoint,};routeBuilder.MapRoute("default","{item=home}");routeBuilder.MapRoute("other","other/{item=other_home}");app.UseRouter(routeBuilder.Build());}

如果有一些特殊的的路由配置,我们也可以使用routeBuilder.Routes.Add(route);这代码来添加。至于能配置的模板都有些什么,可以看 Routing 的 Template 的测试类:https://github.com/aspnet/Routing/tree/dev/test/Microsoft.AspNetCore.Routing.Tests/Template 看完基本就知道都有些什么样的模板格式可以使用了。

实现自己的 RouteHandler

到现在,我们已经知道了Routing大概是怎么运行起来,知道了如何简单的使用。那么接下来可以来创建一个自己的RouteHandler,来加深一下对Routing的使用体验。

创建一个类MyRouteHandler,实现接口IRoute:

public class MyRouteHandler : IRouter
{public VirtualPathData GetVirtualPath(VirtualPathContext context){        return null;}public Task RouteAsync(RouteContext context){context.Handler = (c) =>{var printStr = $"controller:{c.GetRouteValue("controller")}," +$"action:{c.GetRouteValue("action")},id:{c.GetRouteValue("id")}";            return c.Response.WriteAsync(printStr);};        return TaskCache.CompletedTask;}
}

然后我们的路由配置改成这样:

    public void Configure(IApplicationBuilder app)    {        var endpoint = new MyRouteHandler();        var routeBuilder = new RouteBuilder(app){DefaultHandler = endpoint,};routeBuilder.MapRoute("default","{controller=Home}/{action=Index}/{id?}");app.UseRouter(routeBuilder.Build());}

然后打开浏览器http://localhost:5000/ 打印出来的内容是 controller:Home,action:Index,id: 。这样是不是很像我们去调用mvc的控制器和控制器的行为呢?Routing的体验文章到这来就结束了,谢谢观看。

相关文章:

  • ASP.NET Core 1.0 入门——了解一个空项目

  • ASP.NET Core 1.0 部署 HTTPS (.NET Framework 4.5.1)

  • .NET Core 1.0、ASP.NET Core 1.0和EF Core 1.0简介

  • 云服务器下ASP.NET Core 1.0环境搭建(包含mono与coreclr)

  • 使用VS Code开发ASP.NET Core 应用程序

  • dotnet run是如何启动asp.net core站点的

  • ASP.NET Core提供模块化Middleware组件

  • “dotnet restore"和"dotnet run"都做了些什么?

  • 探秘 dotnet run 如何运行 .NET Core 应用程序

  • .NET Portability Analyzer 已开源

  • ASP.NET Core的配置(1):读取配置信息

  • ASP.NET Core的配置(2):配置模型详解

  • .NET Core 1.0 RC2 历险之旅

  • 使用VS Code开发 调试.NET Core 应用程序

  • 让我们Core在一起:ASP.NET Core & .NET Core

  • .NET Core VS Code 环境配置

  • 官方博客明确了 .NET Core RC2/RTM 时间表

  • .NET Core全新的配置管理[共9篇]

  • 利用记事本创建一个ASP.NET Core RC2 MVC应用

  • 微软.NET 正式劈腿成功,横跨所有平台

  • .NET Core 1.0 CentOS7 尝试

  • 解读发布:.NET Core RC2 and .NET Core SDK Preview 1

  • [.NET Core].NET Core R2安装及示例教程

  • ASP.NET Core 开发-中间件(Middleware)

  • 结合Jexus + Kestrel 部署 asp.net core 生产环境

  • 通过Jexus 部署 dotnetcore版本MusicStore 示例程序

  • ASP.NET Core 中文文档 第一章 入门

  • 用 Visual Studio Code 在 macOS 上创建首个 ASP.NET Core 应用程序

  • 用 Visual Studio 和 ASP.NET Core MVC 创建首个 Web API

  • 用 Visual Studio 发布一个 Azure 云 Web 应用程序

  • ASP.NET Core MVC 与 Visual Studio 入门

  • 第二章指南(4.2)添加 Controller

  • DotNet Core 介绍

  • asp.net core 中间件详解及项目实战

  • 教你实践ASP.NET Core Authorization(免看文档教程)

  • asp.net core 使用 Redis 和 Protobuf 进行 Session 缓存

  • asp.net core 中间件详解及项目实战

  • 第二章 指南(4.3)添加 View

原文地址:http://www.cnblogs.com/caipeiyu/p/5597775.html


.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

dotnet core 开发体验之Routing相关推荐

  1. dotnet core开发体验之开始MVC

    开始 在上一篇文章:dotnet core多平台开发体验 ,体验了一把dotnet core 之后,现在想对之前做的例子进行改造,想看看加上mvc框架是一种什么样的体验,于是我就要开始诞生今天的这篇文 ...

  2. vs2017 js cordova + dotnet core 开发app

    原文:vs2017 js cordova + dotnet core 开发app 1.记得在index.html加入 <meta http-equiv="Content-Securit ...

  3. dotnet core 开发无缝兼容Http和Websocket协议的接口服务

    在应用接口开发中往往要针对不同协义开发相应的代理服务,但对于Websocket和http这两种协议来说就有些不同,从实现上来看Websocket可以说是Http的升级子协议, 两者在协议处理上基本一致 ...

  4. ASP.NET Core 开发-Entity Framework (EF) Core 1.0 Database First

    ASP.NET Core 开发-Entity Framework Core 1.0 Database First,ASP.NET Core 1.0 EF Core操作数据库. Entity Frame ...

  5. MongoDB via Dotnet Core数据映射详解

    用好数据映射,MongoDB via Dotnet Core开发变会成一件超级快乐的事.   一.前言 MongoDB这几年已经成为NoSQL的头部数据库. 由于MongoDB free schema ...

  6. dotnet core 微服务教程

    这个教程主要是对于第一次使用dotnet core开发的同学. 运行环境是在centos 7 , 使用了docker容器. 即这是一篇运行在linux的docker容器上的微服务的简单应用. 一. 安 ...

  7. 手把手教你使用spring cloud+dotnet core搭建微服务架构:服务治理(-)

    背景 公司去年开始使用dotnet core开发项目.公司的总体架构采用的是微服务,那时候由于对微服务的理解并不是太深,加上各种组件的不成熟,只是把项目的各个功能通过业务层面拆分,然后通过nginx代 ...

  8. 基于DotNet Core的RPC框架(一) DotBPE.RPC快速开始

    0x00 简介 DotBPE.RPC是一款基于dotnet core编写的RPC框架,而它的爸爸DotBPE,目标是实现一个开箱即用的微服务框架,但是它还差点意思,还仅仅在构思和尝试的阶段.但不管怎么 ...

  9. [ASP.NET Core 3框架揭秘] 跨平台开发体验: Mac OS

    除了微软自家的Windows平台, .NET Core针对Mac OS以及各种Linux Distribution(RHEL.Ubuntu.Debian.Fedora.CentOS和SUSE等)都提供 ...

最新文章

  1. 微软关于XP退役的进一步说明。
  2. linux安装python虚拟环境_linux环境下安装python虚拟环境及注意事项
  3. 详解@EnableEurekaServer和@EnableDiscoveryClient 或 @EnableEurekaClient注解
  4. 彻底的卸载SQL Server2005
  5. Java多线程(六)之Deque与LinkedBlockingDeque深入分析
  6. 乘基取整法是什么_十进制小数转二进制小数乘2取整法的直观理解
  7. 再读TCP/IP网络7层协议
  8. java私有成员的访问_java – 使用私有成员或公共访问器的方法
  9. 让人欲罢不能的量子学
  10. 进程间传递文件描述符--sendmsg,recvmsg(可用)
  11. 学在LINUX下编程(转)
  12. access连接mysql_如何正确连接access数据库
  13. 找回微信人工服务器,微信找回密码人工服务
  14. 使用Python、pandas、pyecharts进行数据分析——实例讲解
  15. epub 电子书文件如何使用浏览器打开
  16. 伦巴时间步的动作要领_伦巴前进步动作的基本要领
  17. [LaTeX] 调整参考文献的格式(References),包括作者名缩写,行距,字体,引用顺序等等
  18. 大数据存储基石——HDFS
  19. 植物大战僵尸2android最新版,植物大战僵尸2
  20. Web3能否撕裂国内 VC 的共识?

热门文章

  1. c++ memcpy与strcpy的比较
  2. Oracle迁移索引
  3. [导入]php 安全基础 第八章 共享主机 文件系统浏览
  4. C#语法糖 Null 条件运算符 【?.】
  5. C# 使用TCP创建HTTP客户程序
  6. 基于事件驱动架构构建微服务第16部分:Azure Active Directory B2C
  7. .NET 大会今日开幕 |这些白嫖福利不看肠子都悔青
  8. 验证规则构建神器 FluentValidation.md
  9. 实际体验SpanT 的惊人表现
  10. 如何在 ASP.Net Core 中使用 Serilog