Статический анализ кода важен. Особенно, если Вы работаете с чужим кодом.
мне нравится CodeHealer, который является большим для установки флага очень важного и в других отношениях трудного определить местоположение проблем.
Причина использования DenyGet по умолчанию - MSDN со ссылкой на блог Фила Хаака для получения дополнительных сведений. Похоже на уязвимость межсайтового скриптинга.
HTTP GET отключен по умолчанию как часть защиты от подделки межсайтовых запросов (CSRF / XSRF) ASP.NET. Если ваши веб-службы принимают запросы GET, они могут быть уязвимы для сторонних сайтов, отправляющих запросы через теги
и потенциально собирающих ответ, изменяя сеттеры JavaScript.
Однако стоит отметить, что отключения запросов GET недостаточно для предотвращения атак CSRF, и это не единственный способ защитить вашу службу от типа атак, описанных выше. См. Надежная защита от подделки межсайтовых запросов , где представлен хороший анализ различных векторов атак и способы защиты от них.
I don't know if this is the reason they chose to change that default, but here's my experience:
When some browsers see a GET, they think they can cache the result. Since AJAX is usually used for small requests to get the most up-to-date information from the server, caching these results usually ends up causing unexpected behavior. If you know that a given input will return the same result every time (e.g. "password" cannot be used as a password, no matter when you ask me), then a GET is just fine, and browser caching can actually improve performance in case someone tries validating the same input multiple times. If, on the other hand, you expect a different answer depending on the current state of the server-side data ("myfavoriteusername" may have been available 2 minutes ago, but it's been taken since then), you should use POST to avoid having the browser thinking that the first response is still the correct one.
У меня также была ваша проблема, когда я перенес свой веб-сайт MVC из Visual Studio 2008 в Visual Studio 2010.
Основной aspx ниже, у него есть ViewData, который вызывает Контроллер категорий для заполнения ViewData ["Категории "] с коллекцией SelectList. Также есть сценарий для вызова Контроллера подкатегории, чтобы заполнить вторую комбинацию с помощью javascript. Теперь я смог исправить это, добавив атрибут AlloGet на этот второй контроллер.
Вот 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" />
<%}%>
вот мой контроллер для подкатегорий
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); }
}