ASP.NET Core: TemplateMatcher 忽略类型约束问题的解决方法

在使用ASP.NET Core中的TemplateMatcher解决route template匹配字符串问题时,遇到的一个新问题:匹配时忽略类型约束。我们将通过分析源代码和查找相关线索,提供一种解决方案来解决这个问题。

ASP.NET Core

引言

在使用ASP.NET Core开发Web应用程序时,我们经常需要进行URL路由的匹配。ASP.NET Core提供了TemplateMatcher类,它可以帮助我们实现route template与URL路径的匹配。然而,在使用TemplateMatcher解决一些基本的route template匹配问题后,我们发现了一个新的问题:当route template中包含类型约束(即inline constraint)时,匹配过程会忽略这些类型约束。本文将介绍如何解决这个问题。

使用 TemplateMatcher 的实现代码如下:

var routeTemplate = TemplateParser.Parse(template);                
var values = new RouteValueDictionary();
var matcher = new TemplateMatcher(routeTemplate, values);
if (matcher.TryMatch(path, values))
{
    return new KeyValuePair<string, RouteValueDictionary>(template, values);
}

分析

我们首先需要了解TemplateMatcher是如何进行路由匹配的。在TemplateMatcher的实现代码中,我们可以看到它使用了TemplateParser来解析route template,并将解析结果传递给TemplateMatcher进行匹配。然而,在TemplateParser.Parse方法返回的解析结果中,并没有提供对类型约束的支持。

解决方案

通过查看ASP.NET Core的源代码,我们发现在IntRouteConstraintsTests.cs#L22和ConstraintsTestHelper.cs#L8中有一些重要的线索,我们可以利用这些线索来解决这个问题。

首先,我们可以使用下面的代码将TemplateParser.Parse方法返回结果中的InlineConstraints打印出来:

var routeTemplate = "/{blogApp}/{postType}/{id:int}/{**slug}";
var parsedTemplate = TemplateParser.Parse(routeTemplate);
var values = new RouteValueDictionary();
foreach (var parameter in parsedTemplate.Parameters)
{
    foreach (var inlineConstraint in parameter.InlineConstraints)
    {
        Console.WriteLine(parameter.Name + ":" + inlineContraint.Constraint);
    }
}

输出:

id:int

从输出结果中我们可以看到,InlineConstraints中包含了类型约束的信息。接下来,我们需要创建一个IRouteConstraint的实例,并将解析出的类型约束传递给它。我们可以使用以下代码创建IRouteConstraint实例:

IServiceCollection services = new ServiceCollection();
services.AddOptions<RouteOptions>();
using ServiceProvider sp = services.BuildServiceProvider();
var routeOptions = sp.GetRequiredService<IOptions<RouteOptions>>();
var constraintResolver = new DefaultInlineConstraintResolver(routeOptions, sp);

var routeConstraint = constraintResolver.ResolveConstraint(inlineContraint.Constraint);
Console.WriteLine(routeContraint);

输出:

Microsoft.AspNetCore.Routing.Constraints.IntRouteConstraint

通过以上代码,我们成功创建了一个IntRouteConstraint的实例。现在我们可以将这个实例用于匹配过程中。

接下来,我们可以使用以下代码演示如何使用TemplateMatcher进行URL路径的匹配,并考虑到类型约束:

using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.Routing.Template;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;

var routeTemplates = new[]
{
    "/{blogApp}/{postType}/{id:int}/{**slug}",
    "/{blogApp}/{postType}/{idOrSlug}.html"
};

var url = "https://www.toymoban.com/diary/problem/681.html";
var urlPath = new Uri(url).AbsolutePath;

IServiceCollection services = new ServiceCollection();
services.AddOptions<RouteOptions>();
using ServiceProvider sp = services.BuildServiceProvider();
var routeOptions = sp.GetRequiredService<IOptions<RouteOptions>>();
var constraintResolver = new DefaultInlineConstraintResolver(routeOptions, sp);

foreach (string routeTemplate in routeTemplates)
{
    Console.WriteLine("routeTemplate: " + routeTemplate);
    var parsedTemplate = TemplateParser.Parse(routeTemplate);

    var values = new RouteValueDictionary();
    var matcher = new TemplateMatcher(parsedTemplate, values);
    if (matcher.TryMatch(urlPath, values))
    {
        Console.WriteLine("TemplateMatcher matched: true");
        foreach (var item in values)
        {
            Console.WriteLine("{0}: {1}", item.Key, item.Value);
        }

        foreach (var parameter in parsedTemplate.Parameters)
        {
            foreach (var inlineConstraint in parameter.InlineConstraints)
            {
                Console.WriteLine(parameter.Name + ":" + inlineConstraint.Constraint);

                var routeConstraint = constraintResolver.ResolveConstraint(inlineConstraint.Constraint);
                var routeDirection = RouteDirection.IncomingRequest;
                bool matched = routeConstraint!.Match(httpContext: null, route: null, parameter.Name!, values, routeDirection);

                Console.WriteLine($"{routeConstraint.GetType().Name} matched: {matched}");
                Console.WriteLine();
            }
        }
    }
}

输出:

routeTemplate: /{blogApp}/{postType}/{id:int}/{**slug}
TemplateMatcher matched: true
blogApp: diary
postType: problem
id: 681.html
slug:
id:int
IntRouteConstraint matched: False

routeTemplate: /{blogApp}/{postType}/{idOrSlug}.html
TemplateMatcher matched: true
blogApp: diary
postType: problem
idOrSlug: 681.html

通过以上代码,我们可以看到TemplateMatcher成功匹配了URL路径,并正确应用了类型约束。在第一个匹配的例子中,我们使用了"/{blogApp}/{postType}/{id:int}/{**slug}"的route template,其中id参数被指定为整数类型约束。在匹配过程中,我们可以看到IntRouteConstraint成功被应用,并返回了匹配结果。

结论

通过分析源代码和查找相关线索,我们成功解决了TemplateMatcher忽略类型约束的问题。我们使用DefaultInlineConstraintResolver创建了一个IRouteConstraint的实例,并将解析出的类型约束传递给它。这样,在进行URL路径匹配时,TemplateMatcher会正确应用类型约束,从而得到准确的匹配结果。

ASP.NET Core的TemplateMatcher是一个强大的工具,可以帮助我们处理URL路由的匹配。然而,在使用它时,我们需要注意到一些潜在的问题,比如忽略类型约束。通过本文提供的解决方案,我们能够充分利用TemplateMatcher的功能,并确保类型约束得到正确应用。

注意

以上代码仅为示例,可能需要根据您的实际需求进行适当修改。

可以参考以下资料:文章来源地址https://www.toymoban.com/article/681.html

[Stack Overflow](stackoverflow.com)
[Microsoft Documentation](docs.microsoft.com/en-us/aspnet/core/?view=aspnetcore-5.0)

到此这篇关于ASP.NET Core: TemplateMatcher 忽略类型约束问题的解决方法的文章就介绍到这了,更多相关内容可以在右上角搜索或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

阅读剩余 52%

原文地址:https://www.toymoban.com/article/681.html

如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请联系站长进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • asp.net core 6中跨域问题

    1.在使用 .net 6 开发WEBAPI程序时,出现跨域问题 。原来的写法不能用了。用下面的写法解决问题 builder.Services.AddCors(options = {     options.AddPolicy(\\\"any\\\", builder =     {         builder.SetIsOriginAllowed(_ = true).AllowAnyMethod().AllowAnyHeader().AllowCredentials();     }); });   app.UseCors(\\\"any\\\");

    2024年02月16日
    浏览(36)
  • ASP.NET core WebApi Cors跨域解决

    ASP.NET core WebApi Cors跨域解决

    我用了最新版的Asp.net webapi ,在csdn上面搜跨域如何解决的时候,发现csdn上面对于.NET技术讨论不是很多。没办法,只能面向官方文档和GitHub编程了。 前面两个已经放弃维护了,我们就不用了。用最新的webApi 我们引入了最新的api后可以在官方网址上查看文档(有些地址是gitH

    2024年04月29日
    浏览(37)
  • 一个基于ASP.NET Core完全开源的CMS 解决方案

    一个基于ASP.NET Core完全开源的CMS 解决方案

    MixCore CMS是一个基于.NET Core框架的开源内容管理系统(CMS),提供了丰富的的基础功能和插件,是一款面向未来的企业 Web  CMS ,可轻松构建任何类型的应用程序。集成了Google Analytics分析,以及友好的Seo功能,非常适合用于创建企业网站、内容系统、个人博客,也可以用于开发

    2024年02月05日
    浏览(43)
  • bug笔记:解决 HTTP Error 500.30 - ASP.NET Core app failed to start

    bug笔记:解决 HTTP Error 500.30 - ASP.NET Core app failed to start

    总结下后端部署windos iis环境net6版本,500.30问题报错的一种解决方案: 检查下是否安装了net6对应的环境,是否已经安装 然后在事件管理器Windows日志应用程序,里面查看详细异常记录 在iis下面找到部署的后端,找到右侧栏的编辑权限,给Everyone用户授权。

    2024年01月20日
    浏览(38)
  • ASP.NET Core教程:ASP.NET Core 程序部署到Windows系统

    ASP.NET Core教程:ASP.NET Core 程序部署到Windows系统

    本篇文章介绍如何将一个ASP.NET Core Web程序部署到Windows系统上。这里以ASP.NET Core WebApi为例进行讲解。首先创建一个ASP.NET Core WebApi项目,使用默认的Values控制器,这里使用Visual Studio 2019创建一个ASP.NET Core 3.1d的WebApi项目。 创建新项目的时候选项ASP.NET Core Web应用程序,如下图所

    2023年04月08日
    浏览(37)
  • ASP.NET Core MVC -- 将视图添加到 ASP.NET Core MVC 应用

    ASP.NET Core MVC -- 将视图添加到 ASP.NET Core MVC 应用

    右键单击“视图”文件夹,然后单击“添加”“新文件夹”,并将文件夹命名为“HelloWorld”。 右键单击“Views/HelloWorld”文件夹,然后单击“添加”“新项”。 在“添加新项 - MvcMovie”对话框中: 在右上角的搜索框中,输入“视图” 选择“Razor 视图 - 空” 保持“名称”框的

    2024年02月13日
    浏览(54)
  • ASP.NET和ASP.NET Core的区别

    ASP.NET和ASP.NET Core是两个不同的Web应用程序框架,它们都是由Microsoft开发的。ASP.NET是Microsoft推出的第一个Web应用程序框架,而ASP.NET Core是其最新版本。本文将介绍ASP.NET和ASP.NET Core的简介和区别。 ASP.NET的简介 ASP.NET是一个基于.NET框架的Web应用程序框架,它是Microsoft推出的第一

    2024年02月16日
    浏览(41)
  • Asp.Net VS ASP.NET Core 请求管道

    Asp.Net VS ASP.NET Core 请求管道

    参考链接 ASP.NET CORE 启动过程及源码解读 请求进入Asp.Net工作进程后,由进程创建HttpWorkRequest对象,封装此次请求有关的所有信息,然后进入HttpRuntime类进行进一步处理。HttpRuntime通过请求信息创建HttpContext上下文对象,此对象将贯穿整个管道,直到响应结束。同时创建或从应用

    2024年02月04日
    浏览(41)
  • 【ASP.NET Core 基础知识】--最佳实践和进阶主题--设计模式在ASP.NET Core中的应用

    一、设计模式概述 1.1 什么是设计模式 设计模式是在软件设计过程中反复出现的、经过验证的、可重用的解决问题的方法。它们是针对特定问题的通用解决方案,提供了一种在软件开发中可靠的指导和标准化方法。设计模式通常描述了一种在特定情景下的解决方案,包括了问

    2024年02月21日
    浏览(321)
  • ASP.NET Core SingleR Core:WebApi + .net 客户端开发

    ASP.NET Core SingleR Core:WebApi + .net 客户端开发

    我之前稍微研究了一下SignalR Core。用起来还行。简单来说SignalR就是用来解决实时通讯的问题的。 ASP.NET Core SingleR:初次体验和简单项目搭建 SignalR支持三种客户端,C#,Java,JavaScirpt。基本够用了。本身就是微软开发的,肯定支持自己的语言。因为是Websocket的上层封装,所以也要支

    2024年01月20日
    浏览(218)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包