Я знаю, что если вы считаете, что нашли ошибку в .NET Framework, вы, скорее всего, ошибаетесь, но именно поэтому я пишу этот вопрос, поэтому, пожалуйста, выслушайте меня.
Я совершенно уверенчто есть разница между маршрутами в .NET 3.5 и .NET 4.0, когда дело касается необязательных параметров.В частности, если у вас есть несколько дополнительных параметров в вашем маршруте.Мне не удалось найти это критическое изменение, отмеченное в каких-либо примечаниях к выпуску .NET 4.0 или MVC 3, поэтому я называю это ошибкой.
РЕДАКТИРОВАТЬ: Эта ошибка проявляется толькосам, когда вы пытаетесь построить URL-адрес маршрута, используя код, такой как url или html помощники в mvc.Если вы действительно запрашиваете URL в браузере, в реальном приложении mvc, это работает просто отлично.Так что, если бы мое тестовое приложение, приведенное ниже, было настоящим приложением mvc, не было бы проблемы, если бы вы попытались запросить '/root/test1'.
. Мне нужно, чтобы вы запустили следующую тестовую программу:должно быть достаточно понятным, но в основном он просто устанавливает маршрут с некоторыми необязательными параметрами.
Создание нового консольного приложения .NET 4
Измените целевую платформу на «.NET Framework 4» вместо «.NET Framework 4 Client Profile»
Добавьте ссылки на:
System.Web 4.0
Система.Web.Routing 4.0
System.Web.Mvc 3.0
Вставьте следующий код в файл 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();
}
}
Запустите программу и запишите получающиеся URL.
На моем компьютере результат будет:
Test 1: Fail (expected '/root/test1' but was '<null>')
Test 2: Success ('/root/test1/test2')
Test 3: Success ('/root/test1/test2/test3')
Теперь измените целевую платформу на .NET 3.5 addссылки на:
System.Web.Mvc 2.0
System.Web.Routing 3.5
System.Web.Abstrations 3.5
Запустите программу еще раз и увидите, что все 3 теста успешно завершены.
На этот раз результат будет следующим:
Test 1: Success ('/root/test1')
Test 2: Success ('/root/test1/test2')
Test 3: Success ('/root/test1/test2/test3')
Так что мне кажется, что естьошибка в .NET 4 или MVC 3. Если вы обнаружите ту же проблему, пожалуйста, проголосуйте за следующую проблему в Connect: https://connect.microsoft.com/VisualStudio/feedback/details/630568/url-routing-with-two-optional-parameters-unspecified-fails-on-asp-net-mvc3-rc2#details
Не стесняйтесь проверить это в обычном приложении MVC, если вы думаете, что-то естьнеправильно в тестовой программе.