To do this, I wrote an extension to HtmlHelper called "ActionLinkBack". The methods compose action links back to the same controller an action and merge the existing route values with any new ones that are specified.
public static HtmlString ActionLinkBack(this System.Web.Mvc.HtmlHelper htmlHelper, string linkText, object routeValues)
{
return ActionLinkBack(htmlHelper, linkText, new RouteValueDictionary(routeValues), new RouteValueDictionary());
}
public static HtmlString ActionLinkBack(this System.Web.Mvc.HtmlHelper htmlHelper, string linkText, object routeValues, object htmlAttributes)
{
return ActionLinkBack(htmlHelper, linkText, new RouteValueDictionary(routeValues), new RouteValueDictionary(htmlAttributes));
}
public static HtmlString ActionLinkBack(this System.Web.Mvc.HtmlHelper htmlHelper, string linkText, RouteValueDictionary routeValues)
{
return ActionLinkBack(htmlHelper, linkText, routeValues, new RouteValueDictionary());
}
public static HtmlString ActionLinkBack(this System.Web.Mvc.HtmlHelper htmlHelper, string linkText, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes)
{
// Build a new dictionary of route values based on the previous set
var newRouteValues = new RouteValueDictionary(htmlHelper.ViewContext.RouteData.Values);
// Retain current querystring parameters
var queryString = htmlHelper.ViewContext.HttpContext.Request.QueryString;
if (queryString.Count > 0)
{
foreach (string key in queryString.Keys)
{
newRouteValues[key] = queryString[key];
}
}
// Add and override entries from the list of new route values
if (routeValues != null)
{
foreach (var routeValueItem in routeValues)
{
newRouteValues[routeValueItem.Key] = routeValueItem.Value;
}
}
return new HtmlString(htmlHelper.ActionLink(linkText, null, newRouteValues, htmlAttributes).ToHtmlString());
}
In my reusable "page navigator" view I use the extensions to compose the previous, next, and individual page links:
@Html.ActionLinkBack("Next", new { page = (int)ViewData["Page"] + 1 }, new { @class = "navigationLink" })