任何人都可以在.NET 4.0/MVC3中重新创建我在具有2个或更多可选参数的路由中遇到的以下错误吗?

Joh*_*esH 6 routing .net-4.0 asp.net-mvc-routing asp.net-mvc-3

我知道如果你认为你在.NET框架中发现了一个错误,那你很可能是错的,但这就是我写这个问题的原因,所以请听我说.

我很确定.NET 3.5和.NET 4.0中的路由在可选参数方面有所不同.特别是如果您的路线中有多个可选参数.我无法在.NET 4.0或MVC 3的任何发行说明中找到这种突破性更改,因此我将其称为错误.

编辑:当您尝试使用代码(如mvc中的url或html帮助程序)构建路径URL时,此错误仅会显示.如果您实际在浏览器中请求网址,在实际的mvc应用程序中,它可以正常工作.因此,如果我下面的测试应用程序是一个真正的mvc应用程序,那么如果您尝试请求'/ root/test1'就不会有问题.

我需要你做的是运行以下测试程序,它应该是相当不言自明的,但基本上它只是设置一个带有一些可选参数的路由.

  1. 创建一个新的.NET 4控制台应用程序

  2. 将目标框架更改为".NET Framework 4"而不是".NET Framework 4 Client Profile"

  3. 添加对以下内容的引用:
    System.Web 4.0
    System.Web.Routing 4.0
    System.Web.Mvc 3.0

  4. 将以下代码粘贴到program.cs文件中,覆盖以前的任何内容:

    using System;
    using System.IO;
    using System.Web;
    using System.Web.Mvc;
    using System.Web.Routing;
    
    public class Program
    {
        static void Main()
        {
            var httpCtx = new HttpContextWrapper(new HttpContext(new HttpRequest(null, "http://localhost/", null), new HttpResponse(new StringWriter())));
    
            var routes = RouteTable.Routes;
            routes.MapRoute("Test", "root/{test1}/{test2}/{test3}", new { test2 = UrlParameter.Optional, test3 = UrlParameter.Optional });
    
            var context = new RequestContext(httpCtx , new RouteData());
    
            var url = new UrlHelper(context);
    
            var expected1 = "/root/test1";
            var expected2 = "/root/test1/test2";
            var expected3 = "/root/test1/test2/test3";
    
            var actual1 = url.RouteUrl("Test", new { test1 = "test1" });
            var actual2 = url.RouteUrl("Test", new { test1 = "test1", test2 = "test2" });
            var actual3 = url.RouteUrl("Test", new { test1 = "test1", test2 = "test2", test3 = "test3" });
    
            var result1 = actual1 == expected1;
            var result2 = actual2 == expected2;
            var result3 = actual3 == expected3;
    
            Console.WriteLine("Test 1: {0} ({1})", result1 ? "Success" : "Fail", result1 ? string.Format("'{0}'", actual1) : string.Format("Expected '{0}' but was '{1}'", expected1, actual1 ?? "<null>"));
            Console.WriteLine("Test 2: {0} ({1})", result2 ? "Success" : "Fail", result2 ? string.Format("'{0}'", actual2) : string.Format("Expected '{0}' but was '{1}'", expected2, actual2 ?? "<null>"));
            Console.WriteLine("Test 3: {0} ({1})", result3 ? "Success" : "Fail", result3 ? string.Format("'{0}'", actual3) : string.Format("Expected '{0}' but was '{1}'", expected3, actual3 ?? "<null>" ));
            Console.ReadLine();
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  5. 运行程序,并记下生成的URL.
    在我的机器上,结果是:

    Test 1: Fail    (expected '/root/test1' but was '<null>')
    Test 2: Success ('/root/test1/test2')
    Test 3: Success ('/root/test1/test2/test3')
    
    Run Code Online (Sandbox Code Playgroud)
  6. 现在将目标框架更改为.NET 3.5添加引用:
    System.Web.Mvc 2.0
    System.Web.Routing 3.5
    System.Web.Abstrations 3.5

  7. 再次运行程序,看到3个测试用例都成功.
    这次的结果是:

    Test 1: Success ('/root/test1')  
    Test 2: Success ('/root/test1/test2')  
    Test 3: Success ('/root/test1/test2/test3')
    
    Run Code Online (Sandbox Code Playgroud)

因此,在我看来,.NET 4或MVC 3中存在一个错误.如果您发现同样的问题,请在连接中对以下问题进行投票:https://connect.microsoft.com/VisualStudio/feedback/details/630568/URL路由与-两个可选的参数-非指定失败-ON-ASP净MVC3-RC2#细节

如果您认为测试程序中存在错误,请随意在常规MVC应用程序中对此进行测试.

Joh*_*esH 4

因此,Phil Haack 刚刚发布了一篇博客文章,详细说明这是一个已知问题,将在 .NET 框架的下一个版本中修复,或者如果我们幸运的话,可能会修复特定 dll 的错误。我不太确定他们将如何解决它。他们是否会禁止超过 1 个可选参数,或者是否会按照我在达林答案的评论中概述的方式解决它。至少他们知道这一点,并且可以采取措施在未来使用多个可选参数来指定预期行为。