Can someone recreate the following error that I experience on routes with 2 or more optional parameters in .NET 4.0 / MVC3?

I know that if you think you have found a bug in the .NET platform, most likely you are mistaken, but why am I writing this question, so please listen to me.

I'm pretty sure that there is a difference between routes in .NET 3.5 and .NET 4.0 when it comes to optional parameters. In particular, if your route has more than one optional parameter. I could not find this violation as indicated in the release notes for .NET 4.0 or MVC 3, so I call this a bug.

EDIT: This error only occurs when trying to create a route URL using code such as url or html helpers in mvc. If you really request a URL in a browser, in a real mvc application, it works fine. Therefore, if my test application below was a real mvc application, there would be no problem if you tried to request "/ root / test1".

I need you to run the following test program, it should be clear enough, but basically it just sets up a route with some optional parameters.

  • Create a new .NET 4 console application.

  • Change the target structure to ".NET Framework 4" instead of ".NET Client Client"

  • Add links to:
    System.Web 4.0
    System.Web.Routing 4.0
    System.Web.Mvc 3.0

  • Paste the following code into the program.cs file, overwriting any previous content:

    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 the program and pay attention to the received URLs.
    On my machine, the result is:

     Test 1: Fail (expected '/root/test1' but was '<null>') Test 2: Success ('/root/test1/test2') Test 3: Success ('/root/test1/test2/test3') 
  • Now change the target structure to .NET 3.5, add links to:
    System.Web.Mvc 2.0
    System.Web.Routing 3.5
    System.Web.Abstrations 3.5

  • Run the program again and see how all the test cases are all successful.
    This time the result:

     Test 1: Success ('/root/test1') Test 2: Success ('/root/test1/test2') Test 3: Success ('/root/test1/test2/test3') 

So, it seems to me that there is an error in .NET 4 or MVC 3. If you find the same problem, vote on the following problem in connect: https://connect.microsoft.com/VisualStudio/feedback/details/630568/url- routing-with-two-optional-parameters-unspecified-fails-on-asp-net-mvc3-rc2 # details

Feel free to check it out in a regular MVC application if you think that something is wrong in the test program.

+6
asp.net-mvc-3 asp.net-mvc-routing routing
source share
2 answers

So Phil Haack has just posted a blog post detailing that this is a known issue and will be fixed in the next version of .NET. framework, or maybe if we are lucky, as a bug fix for a specific dll. I'm not quite sure how they will fix it. Will they outlaw more than one optional parameter or will they resolve it as I stated in the comments on Darin. At least they are aware of this and can take steps to indicate expected behavior with more than one optional parameter in the future.

+4
source share

Only the last route definition parameter can be optional, and this rule applies in ASP.NET MVC 3. In your example, you have both test2 and test3 optional, which is not possible. Consider the following URL:

 root/test1/test2 

Given this URL, the routing mechanism cannot say test2="test2" and test3="" or test2="" and test3="test2" . So, why generate a URL that can never be processed back to its constituent tokens?

Now it may be a bug or function, or call it, but in all cases you should avoid such routes. IMHO the error here is that the framework does not throw an exception telling you that only the last parameter in the route definition can be optional, but, of course, this is just my opinion.

+2
source share

All Articles