Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Url.Action based on the current route

Tags:

asp.net-mvc

I'd like to generate a new URL based on the existing route, but will add a new parameter 'page'
Here are a few examples:

old: ~/localhost/something?what=2
new: ~/localhost/something?what=2&page=5

old: ~/localhost/Shoes
new: ~/localhost/Shoes/5

I can not just append &page=5 to existing url because routes may be different.
Some use the query string and some do not.

like image 499
šljaker Avatar asked Feb 11 '10 10:02

šljaker


People also ask

What is a URL action?

A URL action is a hyperlink that points to a web page, file, or other web-based resource outside of Tableau. You can use URL actions to create an email or link to additional information about your data. To customize links based on your data, you can automatically enter field values as parameters in URLs.

What is the use of URL action in MVC?

Action(String, String, Object, String)Generates a fully qualified URL to an action method by using the specified action name, controller name, route values, and protocol to use.

What is URL routing in MVC?

In MVC, routing is a process of mapping the browser request to the controller action and return response back. Each MVC application has default routing for the default HomeController. We can set custom routing for newly created controller.

Can we map multiple URLs to the same action with example?

Yes, We can use multiple URLs to the same action with the use of a routing table. foreach(string url in urls)routes. MapRoute("RouteName-" + url, url, new { controller = "Page", action = "Index" });


2 Answers

I had a similar issue, and took the approach of extending the UrlHelper. The code in the View looks like:

<a href="<%= Url.AddPage(2) %>">Page 2</a>

The UrlHelper extension looks like:

using System.Web.Mvc;
using System.Web.Routing;
using System.Collections.Specialized;

public static class UrlHelperExtension
{
    public static string AddPage(this UrlHelper helper, int page)
    {

        var routeValueDict = new RouteValueDictionary
        {
            { "controller", helper.RequestContext.RouteData.Values["controller"] },
            { "action" , helper.RequestContext.RouteData.Values["action"]}
        };

        if (helper.RequestContext.RouteData.Values["id"] != null)
        {
            routeValueDict.Add("id", helper.RequestContext.RouteData.Values["id"]);
        }

        foreach (string name in helper.RequestContext.HttpContext.Request.QueryString)
        {
            routeValueDict.Add(name, helper.RequestContext.HttpContext.Request.QueryString[name]);
        }

        routeValueDict.Add("page", page);

        return helper.RouteUrl(routeValueDict);
    }
}

A couple of notes: I check for the ID, since I don't use it in all my routes. I add the Page route value at the end, so it is the last url parameter (otherwise you could add it in the initial constructor).

like image 149
jsalwen Avatar answered Sep 20 '22 11:09

jsalwen


This seems like a good approach:

// Clone Current RouteData
var rdata = new RouteValueDictionary(Url.RequestContext.RouteData.Values);

// Get QueryString NameValueCollection
var qstring = Url.RequestContext.HttpContext.Request.QueryString;

// Pull in QueryString Values
foreach (var key in qstring.AllKeys) {
    if (rdata.ContainsKey(key)) { continue; }
    rdata[key] = qstring[key];
}

// Update RouteData
rdata["pageNo"] = "10";

// Build Url
var url = Url.RouteUrl(rdata);

and it avoids collisions such as ?controller=example&action=problem etc.

like image 29
Jack Avatar answered Sep 20 '22 11:09

Jack