válido verbo usando servidor remoto que página puede porque permitido método mostrar lido estã está error busca asp.net asp.net-mvc json

asp.net - verbo - ¿Por qué las solicitudes GET que devuelven JSON no se permiten por defecto?



no se puede mostrar la página que busca porque se está usando un método no válido verbo http (4)

Como parte de la actualización ASP.NET MVC 2 Beta 2, las solicitudes JETO GET no están permitidas por defecto. Parece que necesita establecer el campo JsonRequestBehavior.AllowGet en JsonRequestBehavior.AllowGet antes de devolver un objeto JsonResult desde su controlador.

public JsonResult IsEmailValid(...) { JsonResult result = new JsonResult(); result.Data = ..... ; result.JsonRequestBehavior = JsonRequestBehavior.AllowGet; return result; }

¿Cuál es el razonamiento detrás de esto? Si estoy usando JSON GET para intentar hacer una validación remota, ¿debería usar una técnica diferente?


El motivo del error predeterminado de DenyGet es en MSDN con un enlace al blog de Phil Haack para obtener más detalles. Parece una vulnerabilidad de scripting entre sitios.


HTTP GET está deshabilitado de manera predeterminada como parte de las protecciones de Falsificación de solicitudes entre sitios (CSRF / XSRF) de ASP.NET. Si sus servicios web aceptan solicitudes GET, entonces pueden ser vulnerables a sitios de terceros que realizan solicitudes a través de etiquetas <script /> y potencialmente aprovechar la respuesta al modificar los configuradores de JavaScript.

Sin embargo, vale la pena señalar que deshabilitar las solicitudes GET no es suficiente para evitar los ataques CSRF, ni es la única forma de proteger su servicio contra el tipo de ataque descrito anteriormente. Consulte Defensas robustas para la falsificación de solicitudes entre sitios para un buen análisis de los diferentes vectores de ataque y cómo protegerse de ellos.


No sé si esta es la razón por la que eligieron cambiar ese valor predeterminado, pero esta es mi experiencia:

Cuando algunos navegadores ven un GET, creen que pueden almacenar en caché el resultado. Dado que AJAX se usa generalmente para pequeñas solicitudes para obtener la información más actualizada del servidor, el almacenamiento en caché de estos resultados generalmente termina causando un comportamiento inesperado. Si sabe que una entrada determinada arrojará el mismo resultado cada vez (por ejemplo, "contraseña" no puede usarse como contraseña, no importa cuándo me pregunte), entonces un GET está bien, y el almacenamiento en caché del navegador puede mejorar el rendimiento en caso alguien intenta validar la misma entrada varias veces. Si, por otro lado, espera una respuesta diferente según el estado actual de los datos del lado del servidor ("myfavoriteusername" puede haber estado disponible hace 2 minutos, pero se ha tomado desde entonces), debe usar POST para evitar tener el navegador piensa que la primera respuesta sigue siendo la correcta.


También tuve su problema cuando migré mi sitio web de MVC de Visual Studio 2008 a Visual Studio 2010.

El aspx principal está abajo, tiene un ViewData que llama a un controlador de categoría para completar ViewData ["Categorías"] con la colección SelectList. También hay un script para llamar a un controlador de subcategoría para completar el segundo combo con javascript. Ahora pude arreglarlo agregando el atributo AlloGet en este segundo controlador.

Aquí está el aspx y 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" /> <%}%>

aquí está mi controlador para las subcategorías

public class SubcategoryController : Controller { private MyEntities db = new MyEntities(); public int SubcategoryId { get; set; } public int SubcategoryName { get; set; } public JsonResult Subcategories(int? categoryId) { try { if (!categoryId.HasValue) categoryId = Convert.ToInt32(RouteData.Values["id"]); var subcategories = (from c in db.Subcategories.Include("Categories") where c.Categories.CategoryId == categoryId && c.Active && !c.Deleted && c.Categories.Active && !c.Categories.Deleted orderby c.SubcategoryName select new { SubcategoryId = c.SubcategoryId, SubcategoryName = c.SubcategoryName } ); //just added the allow get attribute return this.Json(subcategories, JsonRequestBehavior.AllowGet); } catch { return this.Json(null); } }