MVC3: использование ActionMethodSelectorAttribute приводит к игнорированию HttpPostAttribute - PullRequest
4 голосов
/ 06 января 2012

Следующий атрибут используется для ограничения использования действия запросом ajax:

public class AjaxRequestAttribute : ActionMethodSelectorAttribute
{
    public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)
    {
        return controllerContext.HttpContext.Request.IsAjaxRequest();
    }
}

У меня определены следующие методы действия контроллера:

[AjaxRequest]
public ActionResult Login()
{
     ...
}

[HttpPost, AjaxRequest]
public ActionResult Login(LoginModel model, string returnUrl)
{
    ...
}

Произошла следующая ошибкакогда создается сообщение ajax:

Текущий запрос действия «Вход в систему» ​​для типа контроллера «AgentController» неоднозначен между следующими методами действия: System.Web.Mvc.ActionResult Login () для типаNappWebsiteMvc.Controllers.AgentController System.Web.Mvc.ActionResult Login (NappWebsiteMvc.Models.Agent.LoginModel, System.String) для типа NappWebsiteMvc.Controllers.AgentController

* 1012при использовании дополнительного атрибута.Если я удаляю атрибут AjaxRequest из двух методов, то код работает.

Какая должна быть правильная реализация?Спасибо!

Ответы [ 3 ]

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

По просьбе Павла, вот код:

public class AjaxGetAttribute : ActionMethodSelectorAttribute
{
    public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
    {
        var isHttpGet = new AcceptVerbsAttribute(HttpVerbs.Get).IsValidForRequest(controllerContext, methodInfo);
        return isHttpGet && controllerContext.HttpContext.Request.IsAjaxRequest();
    }
}

public class AjaxPostAttribute : ActionMethodSelectorAttribute
{
    public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
    {
        var isHttpPost = new AcceptVerbsAttribute(HttpVerbs.Post).IsValidForRequest(controllerContext, methodInfo);
        return isHttpPost && controllerContext.HttpContext.Request.IsAjaxRequest();
    }
}
1 голос
/ 08 октября 2012

Я полагаю, что вы также можете включить атрибут HttpGet в первый метод действия:

[HttpGet, AjaxRequest]
public ActionResult Login()
{
     ...
}

[HttpPost, AjaxRequest]
public ActionResult Login(LoginModel model, string returnUrl)
{
    ...
}

Кажется, что все атрибуты ActionMethodSelector должны возвращать true, чтобы метод действия был действительным.Внесение этого изменения означает, что первый метод не будет использоваться для POST, даже если это Ajax-запрос.

Мой сценарий немного отличается, но это решение сработало для меня.

0 голосов
/ 06 января 2012

Это потому, что HttpPost также расширяет ActionMethodSelectorAttribute со своим собственным IsValidForRequest переопределением. Вы пытались разделить свой атрибут на AjaxRequestAttribute и AjaxPostRequestAttribute?

public class AjaxPostRequestAttribute : HttpPostAttribute
{
    public override bool IsValidForRequest(
        ControllerContext controllerContext, MethodInfo methodInfo)
    {
        var isHttpPost = base.IsValidForRequest(controllerContext, methodInfo);
        return isHttpPost 
            && controllerContext.HttpContext.Request.IsAjaxRequest();
    }
}

Вы бы тогда просто украсили это так:

[AjaxPostRequest]
public ActionResult Login(LoginModel model, string returnUrl)
{
    ...
}

Обновление

Извините, я не заметил запечатанное ключевое слово в источнике HttpPostAttribute.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...