Для чего нужен JsonRequestBehavior?

Почему требуется Json Request Behavior?

Если я хочу ограничить запросы HttpGet моим действием, я могу украсить действие атрибутом [HttpPost]

Пример:

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

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

Почему недостаточно [HttpPost]?
Почему рамка "багирует" нас с JsonRequestBehavior.AllowGet для каждого JsonResult, который у нас есть. Если я хочу отказаться от запросов, я добавлю атрибут HttpPost.

Ответ 1

MVC по умолчанию имеет значение DenyGet, чтобы защитить вас от очень специфической атаки с использованием запросов JSON, чтобы улучшить вероятность того, что последствия разрешения экспозиции HTTP GET рассматриваются заранее, чтобы позволить им произойти.

Это противоречит потом, когда может быть слишком поздно.

Примечание. Если ваш метод действия не возвращает конфиденциальные данные, тогда он должен быть безопасным для доступа.

Дальнейшее чтение из моей книги Wrox ASP.NET MVC3

По умолчанию структура MVC ASP.NET не позволяет вам реагировать на запрос HTTP GET с полезной нагрузкой JSON. Если вам нужно отправить JSON в ответ на GET, вам нужно явно разрешить поведение используя JsonRequestBehavior.AllowGet как второй параметр для Json метод. Однако есть вероятность, что злоумышленник сможет получить доступ к полезную нагрузку JSON через процесс, известный как JSON Hijacking. Ты не хотите вернуть конфиденциальную информацию с помощью JSON в запросе GET. Для более подробно, см. сообщение Фила в http://haacked.com/archive/2009/06/24/json-hijacking.aspx/ или это сообщение SO.

Хаак, Фил (2011). Профессиональный ASP.NET MVC 3 (программа Wrox для Программист) (Kindle Locations 6014-6020). Wrox. Kindle Edition.

Связанный вопрос StackOverflow

В большинстве браузеров-рецензентов (начиная с Firefox 21, Chrome 27 или IE 10) это не более уязвимость.

Ответ 2

Чтобы облегчить себе, вы также можете создать атрибут actionfilter

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

Ответ 3

По умолчанию Jsonresult "Deny get"

Предположим, если у нас есть метод, подобный ниже

  [HttpPost]
 public JsonResult amc(){}

По умолчанию "Deny Get".

В приведенном ниже методе

public JsonResult amc(){}

Если вам нужно разрешить или использовать get, мы должны использовать JsonRequestBehavior.AllowGet.

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

Ответ 4

Улучшение ответа от @Arjen de Mooij, сделав AllowJsonGetAttribute применим к mvc-контроллерам (а не только к отдельным методам действий):

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