The story around routing in ASP.NET MVC is pretty good. When a resource is requested the action that it is routed to is determined and the parameters to the action are initialized. Counter to that when you build a link you specify the argument values and it creates the url for you. So if your routes happen to change your application shouldn’t be bothered by that. One area which can be problematic for this is if you are making any ajax requests. What I’ve done to minimize the impact of route changes to Ajax requests is to have the script make a call to determine the correct route. In the most trivial case this is extremely easy. You call an action, which has a known route, passing into it the name of the action and controller. It returns to you the url for the route. This works really good, but the problem is when your routes have parameters, how do you handle those?
First let’s take a look at the Javascript and then the definition of the action method which it calls.
// wire up the event for the enter button $("#searchText").keypress(function (event) { if (event.keyCode == 13) { // grab the text that is inside the box var text = $("#searchText").val(); var routData = { controllerName: 'Search', actionName: 'Search', paramValues: "{ criteria: '" + text + "' }" }; $.ajax({ url: "/Home/MapRoute", data: routData, success: function (data) { window.location.href = data; }, error: function (data) { alert('there was a failure on the internets'); } }); } });
Here I am building a Javascript object named routeData. This is declared in JSON. One thing to pay attention to is the fact that the value for paramValues is a string containing JSON. This is passed to the controller action.
I’m using jQuery to make an Ajax request to /Home/MapRoute. This maps to the method shown below.
public JsonResult MapRoute(string actionName, string controllerName, string paramValues) { JavaScriptSerializer jss = new JavaScriptSerializer(); Dictionaryparameters = jss.Deserialize >(paramValues); RouteValueDictionary rd = new RouteValueDictionary(); foreach (string key in parameters.Keys) { rd.Add(key, parameters[key]); } UrlHelper urlHelper = new UrlHelper(this.Request.RequestContext); string url = urlHelper.Action(actionName, controllerName, rd); return Json(url, JsonRequestBehavior.AllowGet); }
Here I’m using the JavaScriptSerializer to convert the JSON string into a dictionary, with string as key and value. I use that dictionary to create a RouteValueDictionary which is passed, along with other parameters, into the UrlHelper to generate the url. When you return the Json result you must specify JsonRequestBehavior.AllowGet, otherwise a 500 internal service error will be returned. I think this is new with ASP.NET 2.
When the action method returns, you can use that url. The drawback to this approach is that you will make an extra request to determine the url, but you will be sure that those urls are correct. Also you could cache the results with Output Caching since the routes won’t change.
Sayed Ibrahim Hashimi
Comments are closed.