.net 4.0 任何人都可以重新创建以下bug I';我在.NET 4.0/MVC3中遇到了具有2个或更多可选参数的路由?
我知道如果你认为你在.NET框架中发现了一个bug,那么你很可能是错的,但这就是我为什么要写这个问题的原因,所以请听我说完 我相当肯定.NET3.5和.NET4.0中的路由在可选参数方面存在差异。特别是当路由中有多个可选参数时。我在.NET 4.0或MVC 3的任何发行说明中都找不到这种突破性的变化,所以我称之为bug EDIT:只有当您尝试使用诸如mvc中的url或html帮助程序之类的代码构建路由url时,才会出现此错误。如果你真的在浏览器中请求url,在实际的mvc应用程序中,它可以正常工作。因此,如果我下面的测试应用程序是一个实际的mvc应用程序,那么如果您尝试请求“/root/test1”,就不会出现问题 我需要你做的是运行下面的测试程序,它应该是相当自解释的,但基本上它只是设置了一个带有一些可选参数的路由.net 4.0 任何人都可以重新创建以下bug I';我在.NET 4.0/MVC3中遇到了具有2个或更多可选参数的路由?,.net-4.0,routing,asp.net-mvc-3,asp.net-mvc-routing,.net 4.0,Routing,Asp.net Mvc 3,Asp.net Mvc Routing,我知道如果你认为你在.NET框架中发现了一个bug,那么你很可能是错的,但这就是我为什么要写这个问题的原因,所以请听我说完 我相当肯定.NET3.5和.NET4.0中的路由在可选参数方面存在差异。特别是当路由中有多个可选参数时。我在.NET 4.0或MVC 3的任何发行说明中都找不到这种突破性的变化,所以我称之为bug EDIT:只有当您尝试使用诸如mvc中的url或html帮助程序之类的代码构建路由url时,才会出现此错误。如果你真的在浏览器中请求url,在实际的mvc应用程序中,它可以正常工
System.Web 4.0
System.Web.Routing 4.0
System.Web.Mvc 3.0
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();
}
}
如果您认为测试程序中有问题,可以在常规MVC应用程序中测试此问题。只有路由定义的最后一个参数是可选的,并且此规则已在ASP.NET MVC 3中强制执行。在您的示例中,
test2
和test3
都是可选的,这是不可能的。考虑下面的URL:
root/test1/test2
给定此URL,路由引擎无法说明是test2=“test2”和test3=”“
还是test2=“”和test3=“test2”
。那么,为什么要生成一个永远无法解析回其组成标记的URL呢
现在,也许这是一个bug或一个特性,或者叫它什么的,但在所有情况下,你都应该避免这样的路由。这里的错误是框架没有抛出异常,告诉您只有路由定义中的最后一个参数是可选的,但这当然只是我的意见。因此,Phil Haack刚刚发布了一个详细说明,这是一个已知问题,将在下一版本的.NET framework中修复,或者,如果幸运的话,我们可以修复特定dll的错误。不过,我不确定他们将如何解决这个问题。他们是否会取缔一个以上的可选参数,或者他们是否会按照我在对Darin答案的评论中概述的方式解决它。至少他们知道这一点,并且可以采取措施在将来使用多个可选参数指定预期行为。你好,Darin,谢谢你的回答。在您的示例中,MVC2将设置test2=“test2”,这是解决问题的直观方法,并且允许几个可选参数。我不明白,只要有明确的文件记录,将其指定为可接受的解决方案会有什么问题。正如你所说,很难知道它是否是一个bug。我唯一可以肯定的是,MVC2和MVC3之间存在一个未记录的(突破性的)差异。此外,MVC3中的路由引擎正确路由特定url没有问题。。。是url生成失败了。@JohannesH,我同意你的意见,就是有一个未记录的更改。但当你谈论一种直观的解决问题的方法时,我不同意你的观点:对我来说,两者都是同样可能的。如果
test2
可以为空,并且我们想给test3
一个值,那么为什么这是一种直观的方法呢?你会怎么做?如果两者都是可选的,那么这只是一种情况:test2
为空,test3
有一个值,假设请求此url:root/test1/test2
。对我来说,直观的规则是:“必须按照使用的顺序指定可选参数。”。我同意在指定test3而不是test2的情况下,应该抛出一些异常。在MVC2中,仅将test2参数值设置为“test2”时调用Url.Action的结果就是Url:“/root/test1/test2”,我喜欢这样。但是,只使用test3参数值(设置为“test3”)调用Url.Action会导致Url:“/root/test1/System.Web.Mvc.UrlParameter/test3”,正如我所说,在这种情况下,我宁愿让它抛出一个异常。我相信@Darin Dimitrov关于UrlParameter是错误的。可选误用。这应该是一个错误。文档中没有提到管线定义中最后一个可选参数。同时,C#4.0允许许多方法的可选参数-
Test 1: Success ('/root/test1')
Test 2: Success ('/root/test1/test2')
Test 3: Success ('/root/test1/test2/test3')
root/test1/test2