From 66cb95e94c9d6aa622254c765c4ea1793639f142 Mon Sep 17 00:00:00 2001 From: exyi Date: Tue, 24 Oct 2017 12:08:57 +0000 Subject: [PATCH] DotvvmRoute: optional parameter is ignored when null is assigned resolves #483 --- .../Routing/DotvvmRouteTests.cs | 33 ++++++++++++++++--- src/DotVVM.Framework/Routing/DotvvmRoute.cs | 5 ++- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/src/DotVVM.Framework.Tests.Common/Routing/DotvvmRouteTests.cs b/src/DotVVM.Framework.Tests.Common/Routing/DotvvmRouteTests.cs index 1d61b82790..a9e2fb9c78 100644 --- a/src/DotVVM.Framework.Tests.Common/Routing/DotvvmRouteTests.cs +++ b/src/DotVVM.Framework.Tests.Common/Routing/DotvvmRouteTests.cs @@ -35,7 +35,7 @@ public void DotvvmRoute_IsMatch_RouteMustNotEndWithSlash() public void DotvvmRoute_IsMatch_EmptyRouteMatchesEmptyUrl() { var route = new DotvvmRoute("", null, null, null, configuration); - + IDictionary parameters; var result = route.IsMatch("", out parameters); @@ -77,7 +77,7 @@ public void DotvvmRoute_IsMatch_UrlTwoParametersBothSpecified() Assert.AreEqual("15", parameters["Id"]); Assert.AreEqual("Test-title", parameters["Title"]); } - + [TestMethod] public void DotvvmRoute_IsMatch_UrlTwoParametersOneSpecifiedOneDefault() { @@ -91,7 +91,7 @@ public void DotvvmRoute_IsMatch_UrlTwoParametersOneSpecifiedOneDefault() Assert.AreEqual("15", parameters["Id"]); Assert.AreEqual("test", parameters["Title"]); } - + [TestMethod] public void DotvvmRoute_IsMatch_UrlTwoParametersBothRequired_NoMatchWhenOneSpecified() @@ -246,7 +246,7 @@ public void DotvvmRoute_BuildUrl_Static_TwoParts_TwoParameters_FirstOptionalOpti Assert.AreEqual("~/Article/Test/aaa/suffix", result); } - + [TestMethod] public void DotvvmRoute_BuildUrl_CombineParameters_OneOptional() { @@ -268,6 +268,29 @@ public void DotvvmRoute_BuildUrl_ParameterOnly() Assert.AreEqual("~/", result); } + [TestMethod] + public void DotvvmRoute_BuildUrl_OptionlaParameter() + { + var route = new DotvvmRoute("myPage/{Id?}/edit", null, null, null, configuration); + + var result = route.BuildUrl(new { }); + var result2 = route.BuildUrl(new Dictionary{ ["Id"] = null }); + + Assert.AreEqual("~/myPage/edit", result); + Assert.AreEqual("~/myPage/edit", result2); + } + + [TestMethod] + public void DotvvmRoute_BuildUrl_NullInParameter() + { + var route = new DotvvmRoute("myPage/{Id}/edit", null, null, null, configuration); + + var ex = Assert.ThrowsException(() => { + route.BuildUrl(new Dictionary{ ["Id"] = null }); + }); + Assert.IsInstanceOfType(ex.InnerException, typeof(ArgumentNullException)); + } + [TestMethod] public void DotvvmRoute_BuildUrl_NoParameter() { @@ -293,7 +316,7 @@ public void DotvvmRoute_BuildUrl_Invalid_UnclosedParameter() [TestMethod] - + public void DotvvmRoute_BuildUrl_Invalid_UnclosedParameterConstraint() { Assert.ThrowsException(() => diff --git a/src/DotVVM.Framework/Routing/DotvvmRoute.cs b/src/DotVVM.Framework/Routing/DotvvmRoute.cs index 4e4b9f9b67..5784fce17b 100644 --- a/src/DotVVM.Framework/Routing/DotvvmRoute.cs +++ b/src/DotVVM.Framework/Routing/DotvvmRoute.cs @@ -172,8 +172,7 @@ private string ParseParameter(string prefix, ref int index, Dictionary { - object r; - if (v.TryGetValue(name, out r)) + if (v.TryGetValue(name, out var r) && r != null) { return prefix + r.ToString(); } @@ -185,7 +184,7 @@ private string ParseParameter(string prefix, ref int index, Dictionary prefix + v[name].ToString()); + urlBuilders.Add(v => prefix + (v[name]?.ToString() ?? throw new ArgumentNullException($"Could not build route, parameter '{name}' is null"))); } // add a parameter