Sé que si crees que has encontrado un error en el framework .NET es muy probable que estés equivocado, pero es por eso que estoy escribiendo esta pregunta, así que por favor escúchame.¿Alguien puede recrear el siguiente error que estoy experimentando en rutas con 2 o más parámetros opcionales, en .NET 4.0/MVC3?
Estoy bastante seguro de que existe una diferencia entre las rutas en .NET 3.5 y .NET 4.0 cuando se trata de parámetros opcionales. Específicamente si tiene más de un parámetro opcional en su ruta. No he podido encontrar este cambio radical en notas de la versión de .NET 4.0 o MVC 3, por eso lo llamo un error.
EDIT: Este error solo se manifiesta cuando intentas construir una url de ruta usando un código como url o html helpers en mvc. Si realmente solicita la URL en un navegador, en una aplicación de mvc real, funciona bien. Entonces, si mi aplicación de prueba a continuación fuera una aplicación de mvc real, no habría ningún problema si intentara solicitar '/ root/test1'.
Lo que necesito hacer es ejecutar el siguiente programa de prueba, debe ser bastante fácil de entender, pero básicamente solo establece una ruta con algunos parámetros opcionales.
Crear una nueva aplicación de consola .NET 4
cambiar el marco de destino para '.NET Framework 4' en lugar de' .NET Framework 4 Client Profile'
agregar referencias a:
System.Web 4.0
System.Web.Routing 4.0
System.Web.Mvc 3,0Pega siguiente código al archivo Program.cs, sobrescribir el contenido anterior:
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(); } }
Ejecutar el programa y tenga en cuenta las direcciones URL resultantes.
En mi máquina el resultado es:Test 1: Fail (expected '/root/test1' but was '<null>') Test 2: Success ('/root/test1/test2') Test 3: Success ('/root/test1/test2/test3')
Ahora cambiar el marco de destino para .NET 3.5 agregar referencias a:
System.Web.Mvc 2.0
System.Web.Routing 3,5
sistema. Web.Abstrations 3.5Ejecute el programa de nuevo y vea que los 3 casos de prueba tuvieron éxito.
Esta vez, el resultado es:Test 1: Success ('/root/test1') Test 2: Success ('/root/test1/test2') Test 3: Success ('/root/test1/test2/test3')
Así que me parece que hay un error en el .NET MVC 4 o 3. Si encuentra el mismo problema por favor vote sobre el problema siguiente en la conexión : https://connect.microsoft.com/VisualStudio/feedback/details/630568/url-routing-with-two-optional-parameters-unspecified-fails-on-asp-net-mvc3-rc2#details
Siéntase libre de probar esto en una aplicación MVC normal si cree que hay algo mal en el programa de prueba.
Hola Darin, gracias por la respuesta. En su ejemplo, MVC2 establecería test2 = "test2", que es la forma intuitiva de resolver el problema y que permite varios parámetros opcionales. No veo por qué sería un problema especificar esto como la resolución aceptada, siempre que esté claramente documentada. Como dices es difícil saber si es un error o no. Lo único que puedo decir con certeza es que hay una diferencia no documentada (ruptura) entre MVC2 y MVC3. – JohannesH
Además, el motor de enrutamiento en MVC3 no tiene problemas para enrutar una URL específica correctamente ... Es la generación de URL que no funciona. – JohannesH
@JohannesH, lo que estoy de acuerdo contigo es que hay un cambio no documentado. Pero dejando eso de lado cuando hablas de una forma intuitiva de resolver el problema, no estoy de acuerdo contigo: para mí ambos son igualmente posibles. ¿Por qué esa sería la forma intuitiva si 'test2' puede estar vacío y queremos dar un valor a' test3'? ¿Cómo lo harías tú? Es solo un caso que no puede tener si ambos fueran opcionales: 'test2' empty y' test3' tiene un valor asumiendo que se solicita esta url: 'root/test1/test2'. –