Saturday, March 5, 2011

Routes with non optional parameters

You can define restful routes in asp.net mvc applications. I recently ran into an interesting problem.

I defined the following route.

routes.MapRoute("MemberDetail", "Member/{memberId}", new { controller = "Employee", action = "Details" });
Here I am defining a route named "MemberDetails", that allows user to use urls similar to Member/1234 to get a member's detail.

This route works fine. However somewhere else in the code, when I try to output the route url in a page, by doing the following

UrlHelper.RouteUrl("MemberDetail")

To my surprise I saw an empty string in the page output. I wrote a test to see the problem.

[Test]
public void MemberDetailRoute()
{
Assert.IsNotNull(_mockedUrlHelper.RouteUrl("MemberDetail"))
}

Yes that test fails. It turns out that in case of non optional parameters, I must pass their values for MVC framework to identify the route. So the following test passes.

[Test]
public void MemberDetailRoute()
{
Assert.AreEqual("/Member/123", _mockedUrlHelper.RouteUrl("MemberDetail", new {memberId = 123}))
}

And in a view, if you ever want to dynamically construct the above url using javascript, you could do the following
Here we are using jquery to bind a click event to a button, that grabs the user entered value and gets the member detail url.
<script type="text/javascript">
var memberUrl = '<%: HttpUtility.UrlDecode(Url.RouteUrl("MemberDetail", new {memberId = {0}) )%>';
$('#Go').click(function() {
var memberId = $('#memberId').val(); // get the member id from a textbox
window.location.href = HttpUtility.UrlEncode(url.replace("{0}", memberId));
});
</script>

Here I am passing a dummy value {0} to get the correct url and then replacing that value with the memberId entered by user.
Note that Url.RouteUrl method always encodes the url string.

No comments:

Post a Comment