C# MVC路由识别段错误

C# MVC路由识别段错误,c#,asp.net-mvc,asp.net-mvc-routing,C#,Asp.net Mvc,Asp.net Mvc Routing,我有这条路线: (忽略XML格式) 我希望它能够匹配URL,比如/1234 hello kitty或/5578-a-b-c-ddd-f-g MVC路由处理程序似乎遇到了一些问题 我读了很多关于这个主题的书,发现了一些有趣的事实: MVC首先识别线路段和,然后检查约束 MVC从右向左读取段,这意味着它首先识别标题,然后识别注释ID 举第一个例子,我猜MVC将noteId标识为1234 hello和title标识为kitty 当检查约束时,此操作失败,因此路线不匹配 还有别的方法吗? 请注意

我有这条路线:
忽略XML格式


我希望它能够匹配URL,比如/1234 hello kitty/5578-a-b-c-ddd-f-g

MVC路由处理程序似乎遇到了一些问题

我读了很多关于这个主题的书,发现了一些有趣的事实:

  • MVC首先识别线路段,然后检查约束
  • MVC从右向左读取段,这意味着它首先识别标题,然后识别注释ID
举第一个例子,我猜MVC将noteId标识为1234 hellotitle标识为kitty

当检查约束时,此操作失败,因此路线不匹配

还有别的方法吗?


请注意,我想保留我的两个片段noteIdtitle,它们都应该用连字符隔开
-
(这是必须的

我可以看到解决此问题的两种方法:

重写 一种可能是重写URL(类似于mod_rewrite),将它们从强加给您的格式转换为MVC可以本地路由的格式。有一种方法可以做到这一点,我相信(尽管不确定)在您的情况下将具有完成任务所必需的功能。这里的基本原则是,如果由于路由模板解析规则,MVC无法处理该格式,则在URL到达MVC路由处理之前,将其转换为可以管理的URL。URL重写是一个IIS模块,它位于MVC处理程序之前,检查请求,并能够将请求从一个表单重写为另一个表单。然后,这种经过修改的形式就是MVC所看到的,并且可以被MVC理解和解析。例如,
/1234 hello kitty
的URL可以由模块重写为
/1234/hello kitty
,然后MVC路由模板将是一个简单的
{noteId}/{*title}
。这里的缺点是生成链接可能不起作用,因为生成的链接看起来像
/1234/hello kitty
,而不是
/1234 hello kitty
。然而,缓解措施可能是有一个专门用于链路生成的路由,而不是定义为
{noteId}-{title}
的路由。我相信(应该验证)这实际上会以
/1234 hello kitty
的形式生成一个链接(尽管无法在传入请求时解析)

自定义MVC路由处理程序 这一条基本上借鉴了这样一种思想,即如果MVC不为您做这件事,就重写它的行为来做您希望它做的事情。这方面的战术方面如中所述。使用它的方式是,您可以提供自己对url段解析的解释,以路由数据,并在将它们解析为
requestContext.RouteData.values[“nodeId”]=/*从url获取noteId的代码时提供实际值*/。应用程序的其余部分与其他部分一样工作,对路由中的这种手术干预一无所知

我已经读了很多关于这个主题的书,我发现了一些 有趣的事实:

  • MVC首先识别线路段,然后检查约束
  • MVC从右向左读取段,这意味着它首先识别标题,然后识别注释ID
举第一个例子,我猜MVC正在识别noteId as1234 hellotitleaskitty

如果检查了约束,则此操作失败,因此路线不正确 匹配

这些事实和猜测完全正确。不幸的是,ASP.NET路由就是这样工作的

为什么? ASP.NET路由只需分两个阶段工作,首先解析所有路由,然后尝试为每个请求匹配它们

考虑到您的情况,首先分析:

  • “/”
    拆分
    routeUrl
    。每个段都是一个路径段。您只有一个:
    “{noteId}-{title}”
  • 对于每个路径段,将其拆分为子段:参数和文字。参数由
    {}
    括起,其余为文字。您有3个子段:
    {noteId}
    -
    {title}
然后,尝试匹配(当有多个子段时):

  • 查找最后一个文本(
    -
    )的最后一次出现,并将文本后面的文本与最后一个参数(
    标题
    )匹配
  • 重复第1次以完成所有参数和文字。如果URL或子段较长,则匹配失败
可能的解决方案 因此,为了使用文字,必须确保文字不会出现在参数中。既然你坚持用破折号,你可能会有一些可能的解决办法

  • 您可以使用一个参数,不使用匹配约束的文本(例如,
    ^\d+-[\w-]+$
    ),然后尝试在控制器操作内解析id。这不需要更改现有的URL结构
  • 您可以切换
    title
    noteId
    的位置,如
    /hello-kitty-1234
  • 您可以尝试使用双破折号作为文本,如
    /1234--hellokitty

标题应该是
\w
而不是
+
?标题中可能包含破折号和其他符号,因此\w不够。不过,感谢您的评论:)如果我们没有一个标题可能是什么样子的示例(一个显示标题和您接受的所有有效字符的示例),我们将无法帮助您。你遇到的问题是什么
<route name="note" url="{noteId}-{title}">
    <constraints>
        <segment name="noteId" value="\d+" />
        <segment name="title" value=".+" />
    </constraints>
</route>