So che se pensate di aver trovato un bug nel framework .NET, probabilmente vi sbagliate, ma è per questo che sto scrivendo questa domanda, quindi ascoltatemi.Qualcuno può ricreare il seguente bug che sto riscontrando in percorsi con 2 o più parametri facoltativi, in .NET 4.0/MVC3?
Sono abbastanza certo che c'è una differenza tra i percorsi in .NET 3.5 e .NET 4.0 quando si tratta di parametri opzionali. Specificamente se hai più di un parametro opzionale nel tuo percorso. Non sono stato in grado di trovare questo cambiamento di rottura notato in qualsiasi nota di rilascio di .NET 4.0 o MVC 3, ecco perché lo chiamo bug.
MODIFICA: Questo errore si manifesta solo quando si tenta di creare un URL di instradamento mediante codice come l'url o gli helper html in mvc. Se in realtà richiedi l'url in un browser, in una vera app mvc, funziona perfettamente. Quindi, se la mia app di test qui sotto fosse una vera app per mvc, non ci sarebbe stato un problema se avessi provato a richiedere "/ root/test1".
Quello che devo fare è eseguire il seguente programma di test, dovrebbe essere abbastanza auto-esplicativo, ma in pratica si limita a impostare un percorso con alcuni parametri opzionali.
Creare un nuovo .NET 4 applicazione console
Modificare il framework di destinazione a '.NET Framework 4' invece di' .NET Framework 4 Client Profile'
aggiungere riferimenti a:
System.Web 4.0
System.Web.Routing 4.0
System.Web.Mvc 3,0Incolla seguente codice nel file Program.cs, sovrascrivendo qualsiasi contenuto precedente:
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(); } }
Esegui programma e notare gli URL che ne derivano.
Sulla mia macchina il risultato è:Test 1: Fail (expected '/root/test1' but was '<null>') Test 2: Success ('/root/test1/test2') Test 3: Success ('/root/test1/test2/test3')
Ora cambiare il framework di destinazione per .NET 3.5 aggiungere riferimenti a:
System.Web.Mvc 2.0
System.Web.Routing 3,5
sistema. Web.Abstrations 3.5Eseguire nuovamente il programma e vedere i 3 casi di test tutti riusciti.
Questa volta il risultato è:Test 1: Success ('/root/test1') Test 2: Success ('/root/test1/test2') Test 3: Success ('/root/test1/test2/test3')
Quindi mi sembra ci sia un bug in .NET 4 o MVC 3. Se si trova lo stesso problema si prega di deliberare sul seguente tema in Connect : https://connect.microsoft.com/VisualStudio/feedback/details/630568/url-routing-with-two-optional-parameters-unspecified-fails-on-asp-net-mvc3-rc2#details
Sentitevi liberi di provare questo in una normale applicazione MVC se pensate che ci sia qualcosa di sbagliato nel programma di test.
Ciao Darin, grazie per la risposta. Nel tuo esempio MVC2 avrebbe impostato test2 = "test2", che è il modo intuitivo per risolvere il problema e che consente diversi parametri opzionali. Non vedo perché sarebbe un problema specificarlo come la risoluzione accettata, purché chiaramente documentata. Come dici tu è difficile sapere se è un bug o meno. L'unica cosa che posso dire con certezza è che c'è una differenza non documentata (rottura) tra MVC2 e MVC3. – JohannesH
Inoltre, il motore di routing in MVC3 non ha problemi a instradare correttamente un URL specifico ... È la generazione dell'URL che non funziona. – JohannesH
@JohannesH, la cosa che sono d'accordo con te è che c'è una modifica non documentata. Ma a parte questo, quando parli di un modo intuitivo per risolvere il problema, non sono d'accordo con te: per me entrambi sono ugualmente possibili. Perché questo sarebbe il modo intuitivo se 'test2' può essere vuoto e vogliamo dare un valore a' test3'? Come lo faresti? È solo un caso che non si può avere se entrambi fossero opzionali: 'test2' vuoto e' test3' ha un valore assumendo che sia richiesta l'url: 'root/test1/test2'. –