13

My api client code sends an authentication token in the querystring like:

www.example.com/api/user/get/123?auth_token=ABC123

I'm using Mvc Web api controller, and I have a filter that checks if the auth_token is valid or not, but I'm not sure how to access the request querystring values.

This is what I am doing now but it is obviously wrong:

The below snippet is inside of my filter that inherits from:

ActionFilterAttribute

public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
{
       base.OnActionExecuting(actionContext);

       if (actionContext.Request.Properties.ContainsKey("auth_token") &&
          actionContext.Request.Properties["auth_token"].ToString() == "ABC123")
       {
         ...
       }
}
loyalflow
  • 14,275
  • 27
  • 107
  • 168

3 Answers3

31

Use the GetQueryNameValuePairs extension method, like so:

var queryString = actionContext.Request.GetQueryNameValuePairs().ToDictionary(x => x.Key, x => x.Value);

EDIT To avoid duplicate keys, consider doing a ToLookup:

var queryString = actionContext.Request.GetQueryNameValuePairs().ToLookup(x => x.Key, x => x.Value);

Here's a blog post on Lookups: https://www.c-sharpcorner.com/UploadFile/vendettamit/using-lookup-for-duplicate-key-value-pairs-dictionary/

Sipke Schoorstra
  • 3,074
  • 1
  • 20
  • 28
  • 6
    Butt beware: `ToDictionary` will throw an exception when two parameters with the same key are passed - for instance - [defining an array](https://stackoverflow.com/questions/9981330/pass-an-array-of-integers-to-asp-net-web-api). – AgentFire Mar 19 '18 at 11:15
  • 2
    You're right. Better would be to project the name/value pairs using `ToLookup`. – Sipke Schoorstra Jul 06 '18 at 17:20
  • I like this `GetQueryNameValuePairs()`; here's another approach, using `LastOrDefault(...)` https://stackoverflow.com/a/22432384/1175496 – Nate Anderson Feb 01 '22 at 17:45
10

In the OnActionExecuting method of a filter, you can access the query string and parse it like this to get the token.

var queryString = actionContext.Request.RequestUri.Query;
if(!String.IsNullOrWhiteSpace(queryString))
{
    string token = HttpUtility.ParseQueryString(
                         queryString.Substring(1))["auth_token"];
}

But then, is passing a token in query string a good practice? Probably not, but it is up to you. HTTP header could be a better option since query string can get logged and cached.

0

Another way to do it, similar to Badri's:

string qsValue = string.Empty;
if (Request.QueryString.HasValue)
{
   NameValueCollection queryStringNameValues = HttpUtility.ParseQueryString(Request.QueryString.Value);
   qsValue = queryStringNameValues.Get("auth_token");
}
sscheider
  • 522
  • 5
  • 14