Url 如何让Asp.Net核心路由引擎严格遵守指定的路由?

Url 如何让Asp.Net核心路由引擎严格遵守指定的路由?,url,routing,asp.net-core,seo,Url,Routing,Asp.net Core,Seo,背景 出于搜索引擎优化的目的,重要的是同一页面不能有两个URL,否则谷歌会将其中一个页面视为“重复内容”,这将导致谷歌降低该页面在搜索引擎结果中的排名 问题 在Asp.Net Core中,使用基于属性的例程时,如下所示: public class ExampleController: Controller { [HttpGet] [Route("/example/")] public IActionResult Index() { return Vie

背景
出于搜索引擎优化的目的,重要的是同一页面不能有两个URL,否则谷歌会将其中一个页面视为“重复内容”,这将导致谷歌降低该页面在搜索引擎结果中的排名

问题
在Asp.Net Core中,使用基于属性的例程时,如下所示:

 public class ExampleController: Controller {

    [HttpGet]
    [Route("/example/")]
    public IActionResult Index() {
        return View();
    }     

} 
此路由返回index.cshtml页面,以响应
/example/
/example
的url请求。但是,我只希望它响应我明确指定的路由,即
/example/
。如果请求进入
/example
我不希望此操作方法响应,系统应改为404

问题

我需要在全局级别上做些什么来强制路由引擎严格遵守指定的路由?

我不知道为什么有人否决了这个问题,我只能猜测他们不理解问题的严重性。也许他们不了解搜索引擎优化的重要性。用Asp.Net核心框架研究这个问题花了很多时间,所以我在这里分享这项工作,以帮助其他人

事实证明,这个问题已经出现在GitHub回购协议中,并且正在考虑未来的修复方案。显然,Asp.NETCore表现出这种错误行为的主要原因是MVC的早期版本确实如此。算了吧

目前无法强制Asp.Net核心路由引擎严格匹配声明的路由。事实上,当一个基于属性的路由(如
/example/
)被声明时,它在路由数据结构中内部存储为
/example
,这显示了这个问题的深度。非常不幸的是,数据是以这种方式存储的,这使得路由引擎无法区分
/example
/example/
之间的差异,严格来说,它们是两个不同的端点

解决问题
由于我迫不及待地等待修复,我不得不实施一个变通方案。我解决这个问题的方法是实现在管道早期运行的中间件,该中间件检查所有传入的请求,以确保url仅以斜杠结尾。如果url指定目录路径,该中间件还要求任何以目录结尾的路径都必须以斜杠结尾。如果请求的url不符合这些规则,它将使用301重定向到正确的url

例如,在以下情况下:

/somefile.cshtml
/somedir/anotherdir/file.cshtml
/somedir/anotherdir/index.cshtml

/somefile/
的请求被重定向到
/somefile
/somedir/anotherdir/file/
的请求被重定向到
/somedir/anotherdir/file
,对
/somedir/anotherdir
的请求被重定向到
/somedir/anotherdir/

这种方法解决了默认路由引擎将
/somedir
/somedir/
视为同一路由的固有问题。该方法通过确保其中只有一个能够到达路由引擎来实现这一点


我应该补充一点,虽然这项工作在某种意义上解决了这个问题,但它的效率远不如拥有一个可以被告知严格遵守指定路由的路由引擎。希望我们在2.0版本中有这样一个路由选项。

为什么要这样?这是每个Web服务器使用的一般规则,即尾随斜杠对路由不重要。另外,通常www.example.com的路径通常是
/
,因此它经常被规范化为尾随斜杠。如果你真的想这样做,你可以添加一个中间件,如果尾随斜杠丢失,它总是用尾随斜杠转发到url,但这可能是一个通用的解决方案?我可以添加中间件,但这很混乱,因为大多数URL不应该以斜杠结尾,因为大多数URL将指定一个视图而不是视图目录。我真正想要的是Asp.Net Core遵守我在基于属性的路由中指定的内容,如果有必要,我愿意重写路由引擎的这一部分以获得它。我刚刚发现GitHub上已经报告了这个问题,我在那里添加了信息。对于那些感兴趣的人:如果提供代码有点容易,我会。不幸的是,处理这个问题的代码被嵌入到一个更大的工作主体中,即CanonicalUrlMiddlware模块,因此url是否应该以斜杠结尾只是该中间件的一个小细节。如果您有具体问题,我很乐意回答有关该方法的问题。@RonC如何像您一样识别文件夹或文件案例?@Fantasterei在我的案例中,所有url路径都是小写的,因此我避免了这个问题。我也一样。但是如何找出它是一个文件还是一个目录。我使用了一个IO函数,检查.cshtml文件(不带索引)来识别。有没有更好的方法?@Fantasterei我要做的是维护一个包含所有目录路径的.txt文件,文件中每行一个。然后,当一个say/have/fun请求传入时,我检查文本文件以查看/have/fun/是否存在,如果存在,我会重定向到该文本文件。如果没有,我将继续请求/享受/娱乐。同样,如果请求/not/fun/进来,我会检查目录的.txt文件,看看它是否是有效的目录,如果不是,我会执行301重定向到/not/fun(为了清楚起见,我实际上并没有直接搜索.txt文件,我实际上会将所有这些目录路径加载到一个列表中,以便根据需要进行搜索。)