What's the best way to detect a JSON request on ASP.NET

10,756

Solution 1

Why cant you just pass a bool variable say IsJsonRequest from the client where you are making request?

Then make a check in action method.

or

You could use the request's accept header for this. This indicates what type of content the client wants the server to send to it.

Solution 2

You should be using the request's accept header for this. This indicates what type of content the client wants the server to send to it.

Do not use the request's content type header - this indicates is the type of the body of the request message. By all means set it to "application/json" if you are POSTing or PUTting some Json to the server, but if you are making a GET request then the content type should be empty ( as the body of a GET request is empty ), and if you are posting a multi-part form or something else then it should reflect that type.

The behaviour for forms on web is to set the request content type to 'multipart/form-data' and the accept type to 'text/html'. On the web, overloading the server so that it returns the same type as the request content type whilst ignoring the accept type header would mean that posted forms return encoded form data rather than an html page. This obviously is not the correct behaviour, so don't build your applications around such an interpretation of the request content type.

Solution 3

I found the Pete Kirkham answer very useful. And I think that should be marked as solution.

This is my code according it:

/// <summary>
/// Determines whether the request is a Json Request
/// </summary>
public static bool GetIsJsonRequest(HttpRequest request)
{
    if (request == null)
    {
        throw new ArgumentNullException("request");
    }
    bool rtn = false;
    const string jsonMime = "application/json";

    if (request.AcceptTypes!=null)
    {
        rtn = request.AcceptTypes.Any(t => t.Equals(jsonMime, StringComparison.OrdinalIgnoreCase));
    }
    return rtn || request.ContentType.Split(new[] {';'}, StringSplitOptions.RemoveEmptyEntries).Any(t => t.Equals(jsonMime, StringComparison.OrdinalIgnoreCase));
}

---UPDATE---

Foollowing @Mvision suggestion this is the MVC version:

public static bool GetIsJsonRequest(HttpRequestBase request)
{
    if (request == null)
    {
        throw new ArgumentNullException("request");
    }
    bool rtn = false;
    const string jsonMime = "application/json";

    if (request.AcceptTypes!=null)
    {
        rtn = request.AcceptTypes.Any(t => t.Equals(jsonMime, StringComparison.OrdinalIgnoreCase));
    }
    return rtn || request.ContentType.Split(new[] {';'}, StringSplitOptions.RemoveEmptyEntries).Any(t => t.Equals(jsonMime, StringComparison.OrdinalIgnoreCase));
}

If you need to use this method in both asp.net classic and MVC the second is the suggested one. To convert HttpRequest in HttpREquestBase just wrap it with HttpRequestWrapper:

public static bool GetIsJsonRequest(HttpRequest request)
{
    return GetIsJsonRequest(new HttpRequestWrapper(request));
}

Solution 4

You can use

Request.IsAjaxRequest()

So you can check

if (Request.IsAjaxRequest())
{
   return new JsonResult();
}
return ActionResult
Share:
10,756

Related videos on Youtube

Dax70
Author by

Dax70

Updated on November 21, 2020

Comments

  • Dax70
    Dax70 over 3 years

    Most ajax frameworks seem to standardize with "X-Request-With" on either a header or the query string.

    And in ASP.NET MVC you can use the extension method

    Request.IsAjaxRequest()
    

    Because an ajax client can request several different content types, not just "application/json" ex: "application/xml".

    I'm using the following code snippet/extension method, but I would love to see what others are doing or if there is something I missed, or a better way.

    public static bool IsJsonRequest(this HttpRequestBase request)
    {
        return request.Headers["Accept"].Split(',') 
           .Any(t => t.Equals("application/json", StringComparison.OrdinalIgnoreCase));
    }
    

    Thanks in advance.

    • xelibrion
      xelibrion about 13 years
      Why do you need to detect json accept type? I'm just curious because I use separate methods for JSON results
    • Dax70
      Dax70 about 13 years
      @Xelibrion I'd like to reuse the same actions, no point in duplicate if the only difference is the result type, which I can easily detect with the code above.
  • Bhaskar
    Bhaskar about 13 years
    He wants to identify whether the request is JsonRequest or not. Your code is checking whether it is AjaxRequest or not.
  • Dax70
    Dax70 about 13 years
    thanks, but Request.ContentType does not work, shows "" (Empty String).
  • Dax70
    Dax70 about 13 years
    thanks, but if you look at my example I'm already checking that. However, an ajax request can ask for xml or even html in the case of partials (using MVC). I am looking to filter for requesting specifically JSON.
  • Dax70
    Dax70 about 13 years
    It's a bit redundant, since most ajax api's already have that information or default it. For ex: see "dataType" on api.jquery.com/jQuery.ajax
  • Bhaskar
    Bhaskar about 13 years
    Try this Request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase) It should work!!
  • Dax70
    Dax70 about 13 years
    @Bhaskar, thanks, but that doesnt work. I mentioned on a comment below that Request.ContentType is an empty string, but the header with "application/json" is there.
  • Bhaskar
    Bhaskar about 13 years
    Try setting contentType field in the json request, contentType: "application/json; charset=utf-8",
  • Bhaskar
    Bhaskar about 13 years
    Hey, I have updated my answer try this one Request.AcceptTypes.Contains("application/json")
  • Dax70
    Dax70 about 13 years
    Hi Bhaskar, I change the code a bit with what works. Yes, you were almost right, just a slight tweak. Also, turns out when I tested using $.getJson() of JQuery the content type is not set, but when explicitly setting it using the longer $.ajax(...) works like a charm. Thanks for your help.
  • Michiel Cornille
    Michiel Cornille over 9 years
    Interesting solution, since filterContext.HttpContext.Request is a HttpRequestBase, you could safely alter your code to take in a HttpRequestBase to make it more friendly to us MVC guys trying to use this in attributes :)
  • giammin
    giammin over 9 years
    @Mvision good point! but i'm an old aspnet guy :D and I don't want to wrap my request every time: new HttpRequestWrapper(Context.Request). Anyway I update my answer for young MVC guys :DD
  • Javid
    Javid almost 4 years
    This answer does not answer the question and it's upvoted twice!