3

I need to add an extra (but per user static) query string parameter to all of my rendered urls on my ASP.NET MVC page, including index page. So when the user click on any urls they should see somethin like this in his browsers address bar:

domain.com?extra=code
domain.com/controller/action?extra=code
domain.com/controller/action?otherparams=something&extra=code

etc...

So every url on the page should be rendered containing this extra query string parameter.

How could I do this?

martonx
  • 1,972
  • 4
  • 25
  • 42
  • 2
    Possible duplicate of [Is it possible to change the querystring variable in ASP.NET MVC path before it hits the controller?](http://stackoverflow.com/questions/4558982/is-it-possible-to-change-the-querystring-variable-in-asp-net-mvc-path-before-it) – Alex Art. Nov 30 '15 at 13:39
  • I don't want to change querystring before it hits the controller, I want to modify all the urls rendered on the site. – martonx Nov 30 '15 at 15:55

2 Answers2

2

There's no built-in way to achieve this. About the most reusable way I can think of is to create a UrlHelper extension, and then use that render all URLs across your site:

public static class UrlHelperExtensions
{
    public static string MyAction(this UrlHelper urlHelper, string actionName)
    {
        return urlHelper.Action(actionName) + "?extra=code";
    }
}

Basically proxying all the parameters from your version of the method to the original version, while adding your extra stuff to the end of the generated URL. However, for completeness, you would need to provide equivalent extensions for each of the method signatures (see: https://msdn.microsoft.com/en-us/library/system.web.mvc.urlhelper.action(v=vs.118).aspx#M:System.Web.Mvc.UrlHelper.Action), as well as all the signatures for Url.RouteUrl, in case that is used instead. Additionally, if you want to take advantage of the HTML helpers like Html.ActionLink, you'll need to do the same thing for HtmlHelper as well, creating equivalent extensions for each of the signatures for that as well as Html.RouteLink. Depending on how deep down the rabbit hole you want to go, you may also need to do the same for things like Html.BeginForm. Even with all that, the center only holds as long as every developer for all time that touches the app always uses the custom extensions rather than the built-in helpers for every link.

As should be apparent, this is non-trivial. I would second-guess any business case that required this. Can it be solved another way, a simpler way? For example, if you just need to persist this code between requests, maybe you should just add it to the session? Then, the format of the URL no longer matters.

Chris Pratt
  • 232,153
  • 36
  • 385
  • 444
  • Finally I solved this on client side. I sent the extra code into hidden input, then javascript changes window.history.replaceState to add the code to the url. But your soultion is a good solution for this, so I signed it as solution. Thank you! – martonx Dec 01 '15 at 14:34
  • You should not depend on a pure JavaScript solution. JavaScript can be disabled, and some screenreaders used by the blind do not support it at all. As long as your application still works without the extra bit added to the query string, you're fine. Otherwise, you need a better solution. – Chris Pratt Dec 02 '15 at 13:25
  • I agree with you, just this is a nopcommerce project and it is much more easier to solve something in theme on client side, as changing something into the whole system :( – martonx Dec 03 '15 at 10:32
  • "Easier" is the path to ruin. The right way and the easy way rarely intersect. – Chris Pratt Dec 03 '15 at 13:46
1

When you specify your routes, use your own class derived from Route that overrides GetVirtualPath to add the custom query parameter. For an example, see this answer, which uses the technique to add a subdomain query parameter.

Edward Brey
  • 40,302
  • 20
  • 199
  • 253