什么是在ASP.NET上检测JSON请求的最佳方法

时间:2011-06-03 04:48:10

标签: c# asp.net asp.net-mvc ajax

大多数ajax框架似乎在标头或查询字符串上使用“X-Request-With”进行标准化。

在ASP.NET MVC中,您可以使用扩展方法

Request.IsAjaxRequest()

因为ajax客户端可以请求几种不同的内容类型,而不仅仅是“application / json”ex:“application / xml”。

我正在使用以下代码段/扩展方法,但我希望看到其他人正在做什么,或者是否有我错过的内容或更好的方式。

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

提前致谢。

6 个答案:

答案 0 :(得分:20)

您应该使用请求的accept header。这表示客户端希望服务器向其发送什么类型的内容。

请勿使用请求的content type标头 - 这表示请求消息正文的类型。如果你正在POST或将一些Json放到服务器上,请务必将其设置为“application / json”,但如果你正在发出GET请求,那么内容类型应为空(因为GET请求的主体是空的),如果您要发布多部分表单或其他内容,则应该反映该类型。

Web上表单的行为是将请求内容类型设置为“multipart / form-data”,将accept类型设置为“text / html”。在Web上,重载服务器以使其返回与请求内容类型相同的类型,同时忽略accept类型标头将意味着已发布的表单返回编码的表单数据而不是html页面。这显然不是正确的行为,因此不要围绕对请求内容类型的这种解释来构建应用程序。

答案 1 :(得分:4)

为什么你不能从你提出请求的客户端传递一个bool变量说IsJsonRequest?

然后制作一个检查操作方法。

您可以使用请求的接受标头。这表示客户端希望服务器向其发送什么类型的内容。

答案 2 :(得分:4)

我发现Pete Kirkham answer非常有用。我认为这应该被标记为解决方案。

这是我的代码:

/// <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这是MVC版本:

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));
}

如果您需要在asp.net classic和MVC中使用此方法,则第二个是建议的方法。 要转换HttpRequest中的HttpREquestBase,只需将其HttpRequestWrapper包裹起来:

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

答案 3 :(得分:1)

您可以使用

Request.IsAjaxRequest()

所以你可以检查

if (Request.IsAjaxRequest())
{
   return new JsonResult();
}
return ActionResult

答案 4 :(得分:0)

您可以使用

Request.ContentType 

在您使用的任何控制器方法中。如果需要它可以在多个地方工作,也可以将它放在ActionFilterAttribute中。

答案 5 :(得分:0)

希望这会更有效率

public static class JsonResultController
{
    public static bool IsJsonRequest(this HttpRequestBase request)
    {
        return GetIsJsonRequest(request);
    }

    public static bool IsJsonRequest(this HttpRequest request)
    {
        return GetIsJsonRequest(request);
    }

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

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