2

I'm after an elegant way to append a token to each URL in an ASP.NET MVC application. eg:

http://mysite.com/?token=81541858

From any given page, when a link is generated (eg through HTML.ActionLink) it should append the existing token to the new URL. eg:

HTML.ActionLink("Show me","Detail",new{id=5})

should produce: http://mysite.com/Product/Detail/5?token=81541858

What would be the best way to achieve this while keeping with the existing overall design. An ActionLink wrapper? Perhaps there's some kind of routing-based solution?

nathanchere
  • 8,008
  • 15
  • 65
  • 86

4 Answers4

3

There may be a more elegant MVC/routing solution, but a simple extension method should do the trick:

public static string TokenActionLink(this HtmlHelper html, 
                                     string linkText, 
                                     string actionName, 
                                     string controllerName, 
                                     int id, 
                                     int token)
{
   var anchorFormat = "<a href=\"{0}\">{1}</a>";
   var urlFormat = "{0}/{1}/{2}?token={3}";
   return string.Format(anchorFormat, string.Format(urlFormat, controllerName, actionName, id, token.ToString()), linkText);
}

Usage:

<%: Html.TokenActionLink("Show Me", "Detail", "Product", Model.Id, Model.Token) %>

Or maybe you could create a custom RouteValueDictionary:, and call into the regular ActionLink method from your custom one:

public static string TokenActionLink(this HtmlHelper html, 
                                         string linkText, 
                                         string actionName, 
                                         string controllerName, 
                                         int id, 
                                         int token)
{
     var rvd = new RouteValueDictionary(ViewContext.RouteData.Values);
     rvd["Token"] = token.ToString();
     return Html.ActionLink(linkText, actionName, controllerName, id, rvd);
}
RPM1984
  • 72,246
  • 58
  • 225
  • 350
3

Make a custom TokenActionLink extension method on HtmlHelper, inside of it get the current token value from the querystring and append it to the link querystring. You can have the same overloads as the normal ActionLink and the append..ation of the token key is transparent

public static MvcHtmlString TokenActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, object routeValues)
{
    var token = htmlHelper.ViewContext.RequestContext.HttpContext.Request.QueryString["token"];
    var routeValuesDict = new RouteValueDictionary(routeValues);
    routeValuesDict["token"] = token;
    return htmlHelper.ActionLink(linkText, actionName, routeValuesDict);
}
Simen Echholt
  • 11,243
  • 2
  • 34
  • 26
2

You can append the token like this.

HTML.ActionLink("Show me","Detail",new{id=5, token=myTokenVariable})
John Hartsock
  • 85,422
  • 23
  • 131
  • 146
  • 3
    I think the goal was to make it automatic so that one didn't have to remember to always add the token in the code creating the link. – tvanfosson Nov 23 '10 at 01:10
  • @tvanfosson...The question was not that specific. I was simply trying to provide detail for the ActionLink Helper that OP may not have been aware of. – John Hartsock Nov 23 '10 at 02:35
2

I'd suggest a set of HtmlHelper extensions that use the source for the token and call the actual HtmlHelper extensions, adding the token to the RouteValueDictionary. You'll need to make sure to use your extensions in your views, though.

public static class HtmlHelperExtensions
{

    public static string TokenActionLink( this HtmlHelper helper, string text, string action, object routeValues )
    {
          var token = GetToken(helper);

          var values = new RouteValueDictionary();
          if (routeValues != null)
          {
              values = new RouteValueDictionary( routeValues );
          }
          if (!values.ContainsKey( "token" ))
          {
              values.Add("token", token );
          }

          return helper.ActionLink( action, values );
    }

    ... other custom helpers for different signatures...

    private static string GetToken( HtmlHelper helper )
    {
        ...get token from session or request parameters...
    }
}

Used as:

<%= Html.TokenActionLink( "action", new { id = 5 } ) %>
Pero P.
  • 25,813
  • 9
  • 61
  • 85
tvanfosson
  • 524,688
  • 99
  • 697
  • 795
  • A lot of similar answers which all basically answered the same, but this is the accepted one for the attention to detail. Especially "(!values.ContainsKey( "token" ))". Simple things... – nathanchere Nov 23 '10 at 09:29