2009-05-11 Marek Habersack <mhabersack@novell.com>
authorMarek Habersack <grendel@twistedcode.net>
Mon, 11 May 2009 17:12:11 +0000 (17:12 -0000)
committerMarek Habersack <grendel@twistedcode.net>
Mon, 11 May 2009 17:12:11 +0000 (17:12 -0000)
* UrlPattern.cs: TrySubstitute treats defaults differently
now. They are not consulted when checking if the passed values
match the pattern, but only when substituting the values. Fixes
bug #502555

2009-05-11  Marek Habersack  <mhabersack@novell.com>

* RouteCollectionTest.cs: added test for bug #502555

svn path=/trunk/mcs/; revision=133904

mcs/class/System.Web.Routing/System.Web.Routing/ChangeLog
mcs/class/System.Web.Routing/System.Web.Routing/UrlPattern.cs
mcs/class/System.Web.Routing/Test/System.Web.Routing/ChangeLog
mcs/class/System.Web.Routing/Test/System.Web.Routing/RouteCollectionTest.cs

index 791c29e17179f81e61b373ed57388e532b64c530..7eec2766b26328495734f03115d1c4fe3cd7c87e 100644 (file)
@@ -1,3 +1,10 @@
+2009-05-11  Marek Habersack  <mhabersack@novell.com>
+
+       * UrlPattern.cs: TrySubstitute treats defaults differently
+       now. They are not consulted when checking if the passed values
+       match the pattern, but only when substituting the values. Fixes
+       bug #502555
+
 2009-05-05  Marek Habersack  <mhabersack@novell.com>
 
        * UrlPattern.cs: Match adds defaults values should some keys be
index e6d08bcb7d6d50d7c785c301d4ba481c39f273c9..6b23a0e264c1b5e60f22954b6f9b0f8dd2aad05f 100644 (file)
@@ -39,8 +39,8 @@ namespace System.Web.Routing
                int segmentsCount;
                string [] segments;
                int [] segmentLengths;
-               bool [] segment_flags;          
-               string [] tokens;
+               bool [] segment_flags;
+               List <string> tokens;
 
                public UrlPattern (string url)
                {
@@ -59,7 +59,7 @@ namespace System.Web.Routing
                        if (Url.IndexOf ('?') >= 0)
                                throw new ArgumentException ("Url must not contain '?'");
 
-                       var tokens = new List<string> ();
+                       tokens = new List<string> ();
 
                        segments = Url.Split ('/');
                        segmentsCount = segments.Length;
@@ -98,8 +98,6 @@ namespace System.Web.Routing
                                        from = end + 1;
                                }
                        }
-
-                       this.tokens = tokens.ToArray ();
                }
 
                string SegmentToKey (string segment)
@@ -127,7 +125,7 @@ namespace System.Web.Routing
                                        dict.Add (key, def.Value);
                                }
                        }
-                       
+
                        return dict;
                }
                
@@ -210,32 +208,34 @@ namespace System.Web.Routing
                }
 
                static readonly string [] substsep = {"{{"};
-
+               
                // it may return null for invalid values.
                public bool TrySubstitute (RouteValueDictionary values, RouteValueDictionary defaults, out string value)
                {
-                       var replacements = new RouteValueDictionary ();
                        if (values == null) {
                                value = Url;
                                return true;
                        } else {
-                               object val;
-                               bool missing;
                                foreach (string token in tokens) {
-                                       val = null;
-                                       missing = false;
-                                       if (!values.TryGetValue (token, out val))
-                                               if (defaults == null || !defaults.TryGetValue (token, out val))
-                                                       missing = true;
-                                       if (missing) {
+                                       if (!values.ContainsKey (token)) {
                                                value = null;
                                                return false;
                                        }
-
-                                       replacements.Add (token, val);
                                }
                        }
 
+                       var replacements = new RouteValueDictionary (values);
+                       if (defaults != null) {
+                               string key;
+                       
+                               foreach (var de in defaults) {
+                                       key = de.Key;
+                                       if (replacements.ContainsKey (key))
+                                               continue;
+                                       replacements.Add (key, de.Value);
+                               }
+                       }
+                       
                        // horrible hack, but should work
                        string [] arr = Url.Split (substsep, StringSplitOptions.None);
                        for (int i = 0; i < arr.Length; i++) {
index 6839156b8b4d96de28a7f13e470d3cfd88905c3d..90b08e180098d590df10b4798c802439973336d4 100644 (file)
@@ -1,3 +1,7 @@
+2009-05-11  Marek Habersack  <mhabersack@novell.com>
+
+       * RouteCollectionTest.cs: added test for bug #502555
+
 2009-05-05  Marek Habersack  <mhabersack@novell.com>
 
        * RouteTest.cs: added test for bug #500739
index b14de5585e851fa74d6a9a852bf013f6afad9349..5594a844bb9485f2fa4ec418cb2145768e57639d 100644 (file)
@@ -237,10 +237,61 @@ namespace MonoTests.System.Web.Routing
                        hc.SetResponse (new HttpResponseStub (2));
                        var rd = c.GetRouteData (hc);
                        var vpd = c.GetVirtualPath (new RequestContext (hc, rd), rd.Values);
-                       Assert.AreEqual ("apppath/x/y_modified", vpd.VirtualPath, "#1");
-                       Assert.AreEqual (0, vpd.DataTokens.Count, "#2");
+                       Assert.IsNotNull (vpd, "#1");
+                       Assert.AreEqual ("apppath/x/y_modified", vpd.VirtualPath, "#2");
+                       Assert.AreEqual (0, vpd.DataTokens.Count, "#3");
                }
 
+               [Test (Description = "Bug #502555")]
+               public void GetVirtualPath2 ()
+               {
+                       var c = new RouteCollection ();
+                       
+                       c.Add ("Summary",
+                              new MyRoute ("summary/{action}-{type}/{page}", new MyRouteHandler ()) { Defaults = new RouteValueDictionary (new { controller = "Summary", action = "Index", page = 1}) }
+                       );
+                              
+                       c.Add ("Apis",
+                              new MyRoute ("apis/{apiname}", new MyRouteHandler ()) { Defaults = new RouteValueDictionary (new { controller = "Apis", action = "Index" }) }
+                       );
+                                                           
+                       c.Add ("Single Report",
+                              new MyRoute ("report/{guid}", new MyRouteHandler ()) { Defaults = new RouteValueDictionary (new { controller = "Reports", action = "SingleReport" }) }
+                       );
+                       
+                       c.Add ("Reports",
+                              new MyRoute ("reports/{page}", new MyRouteHandler ()) { Defaults = new RouteValueDictionary (new { controller = "Reports", action = "Index", page = 1 }) }
+                       );
+
+                       c.Add ("Default",
+                              new MyRoute ("{controller}/{action}", new MyRouteHandler ()) { Defaults = new RouteValueDictionary (new { controller = "Home", action = "Index"}) }
+                       );
+
+                       var hc = new HttpContextStub2 ("~/Home/About", String.Empty, String.Empty);
+                       hc.SetResponse (new HttpResponseStub (2));
+                       var rd = c.GetRouteData (hc);
+                       var vpd = c.GetVirtualPath (new RequestContext (hc, rd), rd.Values);
+                       Assert.IsNotNull (vpd, "#A1");
+                       Assert.AreEqual ("/Home/About_modified", vpd.VirtualPath, "#A2");
+                       Assert.AreEqual (0, vpd.DataTokens.Count, "#A3");
+
+                       hc = new HttpContextStub2 ("~/Home/Index", String.Empty, String.Empty);
+                       hc.SetResponse (new HttpResponseStub (2));
+                       rd = c.GetRouteData (hc);
+                       vpd = c.GetVirtualPath (new RequestContext (hc, rd), rd.Values);
+                       Assert.IsNotNull (vpd, "#B1");
+                       Assert.AreEqual ("/Home/Index_modified", vpd.VirtualPath, "#B2");
+                       Assert.AreEqual (0, vpd.DataTokens.Count, "#B3");
+
+                       hc = new HttpContextStub2 ("~/Account/LogOn", String.Empty, String.Empty);
+                       hc.SetResponse (new HttpResponseStub (2));
+                       rd = c.GetRouteData (hc);
+                       vpd = c.GetVirtualPath (new RequestContext (hc, rd), rd.Values);
+                       Assert.IsNotNull (vpd, "#C1");
+                       Assert.AreEqual ("/Account/LogOn_modified", vpd.VirtualPath, "#C2");
+                       Assert.AreEqual (0, vpd.DataTokens.Count, "#C3");
+               }
+               
                [Test]
                [Ignore ("looks like RouteExistingFiles ( = false) does not affect... so this test needs more investigation")]
                public void GetVirtualPathToExistingFile ()