I’m doing a jquery post to an MVC action. The action returns a json result with (for example) Id = 123. Code is still in early stage, but I was very surprised to find out that Url.Action(“action”, “controller”) is building a url complete with the id I returned from Json. Is this magic? I couldn’t find documentation that says it does that.
// how I assumed it would need to be accomplished
// redirects to "Controler/Action/123123" where data = { id = 123 }
$.post(saveUrl, json, function (data) {
var detailsUrl = "@Url.Action("Action", "Control")" + data.id;
window.location = detailsUrl;
});
// rewritten without adding id to the route, not sure how this works...
// redirects to "Controler/Action/123" where data = { id = 123 }
$.post(saveUrl, json, function (data) {
var detailsUrl = "@Url.Action("Action", "Control")";
window.location = detailsUrl;
});
Just for reference, here is the action:
[HttpPost]
public ActionResult Save(Model model)
{
return new JsonResult { Data = new { id = 123 }};
}
So I guess my question is, is this by design? How does it know what to use?
As pointed out in the answer, Url.Action has access to existing routevalues and will attempt to reuse them. To get around this I have used the slightly hacky solution below:
var detailsUrl = "@Url.Action("Action", "Control", new { id = ""})" + "/" + data.id;
This clears out the route values so that I can attach new ones in on the client side. Unfortunately, passing null or new {} as RouteValues to Url.Action does not overcome this. A nicer approach may be to create another Action helper that guarantees no routevalues will be attached. Alternativly, there is also Url.Content, but you will lose the Action/Controller wiring in the IDE doing this.
The
UrlHelper(which is the type forUrl) has access to the route data that was used to access the current action. It will try and use these values to fill in the necessary route values for you, unless you otherwise specify them.