为什么需要Json请求行为?

如果我想限制HttpGet请求到我的动作,我可以用[HttpPost]属性装饰这个动作

例子:

[HttpPost]
public JsonResult Foo()
{
    return Json("Secrets");
}

// Instead of:
public JsonResult Foo()
{
    return Json("Secrets", JsonRequestBehavior.AllowGet);
}

为什么[HttpPost]不是充分的? 为什么框架用JsonRequestBehavior“bug”我们。AllowGet为每个JsonResult。如果我想拒绝get请求,我会添加HttpPost属性。


MVC默认使用DenyGet来保护您免受涉及JSON请求的非常特定的攻击,以提高在允许HTTP GET暴露之前考虑其影响的可能性。

与之相对的是事后,那时可能已经太迟了。

注意:如果您的action方法不返回敏感数据,那么允许get应该是安全的。

进一步阅读我的Wrox ASP。NET MVC3书

By default, the ASP.NET MVC framework does not allow you to respond to an HTTP GET request with a JSON payload. If you need to send JSON in response to a GET, you'll need to explicitly allow the behavior by using JsonRequestBehavior.AllowGet as the second parameter to the Json method. However, there is a chance a malicious user can gain access to the JSON payload through a process known as JSON Hijacking. You do not want to return sensitive information using JSON in a GET request. For more details, see Phil's post at http://haacked.com/archive/2009/06/24/json-hijacking.aspx/ or this SO post. Haack, Phil (2011). Professional ASP.NET MVC 3 (Wrox Programmer to Programmer) (Kindle Locations 6014-6020). Wrox. Kindle Edition.

StackOverflow相关问题

对于大多数最新的浏览器(从Firefox 21、Chrome 27或IE 10开始),这不再是一个漏洞。


默认Jsonresult“Deny get”

假设我们有如下方法

  [HttpPost]
 public JsonResult amc(){}

默认为“Deny Get”。

在下面的方法中

public JsonResult amc(){}

当你需要allowget或使用get时,我们必须使用JsonRequestBehavior.AllowGet。

public JsonResult amc()
{
 return Json(new Modle.JsonResponseData { Status = flag, Message = msg, Html = html }, JsonRequestBehavior.AllowGet);
}

为了让你自己更容易,你也可以创建一个actionfilterattribute

public class AllowJsonGetAttribute : ActionFilterAttribute
{
    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        var jsonResult = filterContext.Result as JsonResult;

        if (jsonResult == null)
            throw new ArgumentException("Action does not return a JsonResult, 
                                                   attribute AllowJsonGet is not allowed");

        jsonResult.JsonRequestBehavior = JsonRequestBehavior.AllowGet;            

        base.OnResultExecuting(filterContext);
    }
}

把它用在你的行动上

[AllowJsonGet]
public JsonResult MyAjaxAction()
{
    return Json("this is my test");
}

改进了@Arjen de Mooij的回答 AllowJsonGetAttribute适用于mvc-controllers(不仅仅是单个动作方法):

using System.Web.Mvc;
public sealed class AllowJsonGetAttribute : ActionFilterAttribute, IActionFilter
{
    void IActionFilter.OnActionExecuted(ActionExecutedContext context)
    {
        var jsonResult = context.Result as JsonResult;
        if (jsonResult == null) return;

        jsonResult.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
    }

    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        var jsonResult = filterContext.Result as JsonResult;
        if (jsonResult == null) return;

        jsonResult.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
        base.OnResultExecuting(filterContext);
    }
}

你不需要它。

如果你的动作有HttpPost属性,那么你不需要费心设置JsonRequestBehavior并使用没有它的重载。没有JsonRequestBehavior枚举的每个方法都有一个重载。他们是:

没有JsonRequestBehavior

protected internal JsonResult Json(object data);
protected internal JsonResult Json(object data, string contentType);
protected internal virtual JsonResult Json(object data, string contentType, Encoding contentEncoding);

与JsonRequestBehavior

protected internal JsonResult Json(object data, JsonRequestBehavior behavior);
protected internal JsonResult Json(object data, string contentType, 
                                   JsonRequestBehavior behavior);
protected internal virtual JsonResult Json(object data, string contentType, 
    Encoding contentEncoding, JsonRequestBehavior behavior);