ASP.NET MVC выбирает неправильное действие контроллера - PullRequest
1 голос
/ 23 февраля 2012

У меня есть контроллер с двумя действиями, которые имеют одинаковое имя, но одно принимает некоторые параметры.Чтобы устранить их неоднозначность, один принимает только запросы GET, а другой - только запросы POST.У меня также есть HttpAjaxAttribute, который используется для принудительного вызова только Ajax-вызовов метода действия.По какой-то причине это решение не является надежным, иногда на запрос GET к действию Import MVC упорно пытается выбрать POST / AJAX один и бросает исключение Ajax из HttpAjaxAttribute.Я нашел вопрос, который может быть связан .Я думал, что наличие атрибутов в определенном порядке (HttpGet или HttpPost, а затем HttpAjax) решит проблему, но это не так.Мой веб-сайт работал некоторое время, и теперь он не работает.Я сталкивался с этой проблемой в случайное время.Как это исправить навсегда?

Действия контроллера

[HttpGet]
public ActionResult Import()
 {
     // some code
 }

[HttpPost]
[HttpAjax]
public ActionResult Import(string country, string state, string city, ImportModel[] locations)
{
    // some code
}

HttpAjaxAttribute

/// <summary>
/// Makes the controller action that has this attribute applied accept only Ajax requests.
/// </summary>
public class HttpAjaxAttribute : ActionMethodSelectorAttribute
{
    public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)
    {
        if (!controllerContext.HttpContext.Request.IsAjaxRequest())
        {
            throw new Exception("The action " + methodInfo.Name + " can only be called via an Ajax request");
        }
        return true;
    }
}

Ответы [ 2 ]

3 голосов
/ 23 февраля 2012

Я почти уверен, что вы не должны выбрасывать исключения из вашего HttpAjaxAttribute. , но просто return false, когда действие не может обслуживать текущий запрос.

/// <summary>
/// Makes the controller action that has this attribute applied accept only Ajax requests.
/// </summary>
public class HttpAjaxAttribute : ActionMethodSelectorAttribute
{
    public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)
    {
        return controllerContext.HttpContext.Request.IsAjaxRequest();
    }
}

MVC попытается проверить всех действий , прежде чем найдет правильное, в этом нет ничего упрямого. Вы должны просто сообщить платформе, является ли действие действительным для текущего запроса, или нет. Наконец, MVC достигнет действия HttpGet и выберет его. Но, бросив исключение до этого, вы принудительно остановите этот процесс.

1 голос
/ 23 февраля 2012

Когда вы добавляете атрибут [HttpAjax], вы ограничиваете свой метод действия или весь контроллер тем, что он может делать.

Когда дело доходит до постепенной деградации, вы хотите проверить, является ли это AJAX-запросом, если он есть, затем вернуть частичное представление, или JSON, или что-то еще, что вы хотите вернуть. В противном случае вам придется вернуть весь вид.

В связи с этим я предлагаю вам не реализовывать атрибут HttpAjax, а проверить в своем методе действия, является ли он AjaxRequest:

public ActionResult Foo()
{
   if(HttpContext.Request.IsAjaxRequest())
   {
       // Return partial
   }

   // Degrade gracefully

}
...