Asp.net 为什么默认情况下不允许GET请求返回JSON?

Asp.net 为什么默认情况下不允许GET请求返回JSON?,asp.net,asp.net-mvc,json,Asp.net,Asp.net Mvc,Json,作为ASP.NET MVC 2 Beta 2更新的一部分,默认情况下不允许JSON GET请求。在从控制器返回JsonResult对象之前,似乎需要将JsonRequestBehavior字段设置为JsonRequestBehavior.AllowGet public JsonResult IsEmailValid(...) { JsonResult result = new JsonResult(); result.Data = ..... ; result.Json

作为ASP.NET MVC 2 Beta 2更新的一部分,默认情况下不允许JSON GET请求。在从控制器返回
JsonResult
对象之前,似乎需要将
JsonRequestBehavior
字段设置为
JsonRequestBehavior.AllowGet

public JsonResult IsEmailValid(...)
{
    JsonResult result = new JsonResult();

    result.Data = ..... ;
    result.JsonRequestBehavior = JsonRequestBehavior.AllowGet;

    return result;
}

这背后的原因是什么?如果我使用JSON GET尝试进行一些远程验证,我应该使用其他技术吗?

DenyGet默认设置的原因是,链接到以获取更多详细信息。看起来像是跨站点脚本漏洞。

我不知道这是否是他们选择更改默认值的原因,但以下是我的经验:


当一些浏览器看到GET时,他们认为可以缓存结果。由于AJAX通常用于从服务器获取最新信息的小请求,因此缓存这些结果通常会导致意外行为。如果您知道给定的输入每次都会返回相同的结果(例如,“密码”不能用作密码,无论您何时问我),那么GET就可以了,浏览器缓存实际上可以提高性能,以防有人尝试多次验证同一输入。另一方面,如果根据服务器端数据的当前状态,您希望得到不同的答案(“myfavoriteusername”可能在2分钟前可用,但从那时起就被使用了),您应该使用POST来避免浏览器认为第一个响应仍然是正确的。

作为ASP.NET跨站点请求伪造(CSRF/XSRF)保护的一部分,HTTP GET在默认情况下被禁用。如果您的web服务接受GET请求,则第三方网站可能会通过
标记发出请求,并可能通过修改JavaScript设置器获取响应,从而使这些服务受到攻击


但是,值得注意的是,禁用GET请求不足以防止CSRF攻击,也不是保护您的服务免受上述类型攻击的唯一方法。有关不同攻击向量的详细分析以及如何防范它们的信息,请参阅。

当我将MVC网站从Visual Studio 2008迁移到Visual Studio 2010时,我也遇到了您的问题

主aspx如下所示,它有一个调用类别控制器的ViewData,以便用SelectList集合填充ViewData[“Categories”]。还有一个脚本可以调用子类别控制器,用javascript填充第二个组合。现在,我能够通过在第二个控制器上添加AlloET属性来修复它

public JsonResult IsEmailValid(...)
{
    JsonResult result = new JsonResult();

    result.Data = ..... ;
    result.JsonRequestBehavior = JsonRequestBehavior.AllowGet;

    return result;
}
这里是aspx和javascript

<head>
<script type="text/javascript" src="../../Scripts/jquery-1.4.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#CategoryId").change(function () {

    var categoryId = $(this)[0].value;

    $("#ctl00_MainContent_SubcategoryId").empty();
    $("#ctl00_MainContent_SubcategoryId").append("<option value=''>-- select a category --</option>");
    var url = "/Subcategory/Subcategories/" + categoryId;

    $.getJSON(url, { "selectedItem": "" }, function (data) {
        $.each(data, function (index, optionData) {
            $("#ctl00_MainContent_SubcategoryId").append("<option value='" + optionData.SubcategoryId + "'>" + optionData.SubcategoryName + "</option>");
        });
        //feed our hidden html field
        var selected = $("#chosenSubcategory") ? $("#chosenSubcategory").val() : '';
        $("#ctl00_MainContent_SubcategoryId").val(selected);

    });

}).change();
});
</script>
<body>
<% using (Html.BeginForm()) {%>
<label for="CategoryId">Category:</label></td>
<%= Html.DropDownList("CategoryId", (SelectList)ViewData["Categories"], "--categories--") %>
<%= Html.ValidationMessage("category","*") %>
<br/>
<label class="formlabel" for="SubcategoryId">Subcategory:</label><div id="subcategoryDiv"></div>
<%=Html.Hidden("chosenSubcategory", TempData["subcategory"])%>
<select id="SubcategoryId" runat="server">
</select><%= Html.ValidationMessage("subcategory", "*")%>
<input type="submit" value="Save" />
<%}%>                

非常有趣的想法。。。您是否有任何链接指向哪些浏览器可能会尝试缓存GET结果以及在什么情况下进行缓存?最常见的示例是Internet Explorer(),但这与其说是哪个浏览器进行缓存的问题,不如说是HTTP规范明确指出,通过GET请求检索的数据是可缓存的。不过,ASP.NET的AJAX框架可能会设置标题,告诉浏览器内容不应缓存,因此这可能与此特定问题无关。我在编写自己的javascript和servlet对以通过AJAX进行通信时遇到了这个问题。我现在已经多次遇到缓存问题,使用POST(甚至不考虑安全问题)无疑是一个好办法。is“JsonRequestBehavior”属性仅在mvc2中添加。因为我试着在MVC1.0上搜索这个,但是没有找到。是的,它是在v2中添加的。至少,这里的1.0文档()没有列出它。老实说,这只是微软的一个非常非常糟糕的决定。。。该漏洞是否会继续存在,或者会产生一些保护,或者是什么?如果我需要返回Json数据,那么我将返回Json数据,而无需明确重复我自己@jalchr:使用AllowGet漏洞仍然存在,您只是告诉框架您不在乎(即,您可以接受,因为您不发送敏感数据)。这是一个CSRF漏洞,而不是跨站点脚本!