I'm building an url using the method:
Url.Action("action", "controller");
I like to pass the querystring for the current request into that url as well.
Something like the following (but it doesn't work):
Url.Action("action", "controller", Request.QueryString);
Converting the QueryString to routevalues is possible with the following extension:
public static RouteValueDictionary ToRouteValues(this NameValueCollection queryString)
{
if (queryString.IsNull() || queryString.HasKeys() == false) return new RouteValueDictionary();
var routeValues = new RouteValueDictionary();
foreach (string key in queryString.AllKeys)
routeValues.Add(key, queryString[key]);
return routeValues;
}
With the extension method the following does work:
Url.Action("action", "controller", Request.QueryString.ToRouteValues());
Is there an other better way ?
Thx
The extension method seems correct and is the way to go.
If you want to easily be able to add additional route value parameters to your Url.Action, try this extension method (based on Linefeed's) which takes an anonymous object and returns a RouteValueCollection:
public static RouteValueDictionary ToRouteValues(this NameValueCollection col, Object obj)
{
var values = new RouteValueDictionary(obj);
if (col != null)
{
foreach (string key in col)
{
//values passed in object override those already in collection
if (key != null && !values.ContainsKey(key)) values[key] = col[key];
}
}
return values;
}
Then you can use it like so:
Url.Action("action", "controller", Request.QueryString.ToRouteValues(new{ id=0 }));
Here's my solution based on pwhe23's answer.
I wanted to keep query string parameters through POST requests (due to a Mvc.Grid) and use just a single action for HTTP GET. CRUD actions are handled by a single page and modal dialogs inside (for insert/update/delete).
So here's my Extension:
public static class MvcExtensions
{
public static RouteValueDictionary ToRouteValues(this NameValueCollection col, Object obj = null)
{
var values = obj != null ? new RouteValueDictionary(obj) : new RouteValueDictionary();
if (col == null) return values;
foreach (string key in col)
{
//values passed in object are already in collection
if (!values.ContainsKey(key)) values[key] = col[key];
}
return values;
}
}
Usage in Controller (e.g. Edit action):
[HttpPost]
public ActionResult Edit(MyModel model)
{
// Some stuff
return RedirectToAction("Index", Request.QueryString.ToRouteValues());
}
Form for edit generated in View (modal dialog is used):
@using (Html.BeginForm("Edit", "SomeControllerName", Request.QueryString.ToRouteValues(), FormMethod.Post))
{
// Some stuff... e.g. dialog content
}