Лучший способ отменить / отменить действие и ответ от ActionFilter - PullRequest
14 голосов
/ 03 марта 2011

Лучший способ отменить / отменить действие из ActionFilter

У меня есть ActionFilter, и предполагается, что соединение должно быть немедленно завершено и возвращено 401 Unauthroized:

public class SignInRequired : ActionFilterAttribute 
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        // User is verified, continue executing action

        if (Acme.Web.CurrentUser != null)
        {
            return;
        }

        // End response with 401 Unauthorized

        var response = HttpContext.Current.Response;
        response.StatusCode = (int)HttpStatusCode.Unauthorized;
        response.End();

        // Prevent the action from actually being executed

        filterContext.Result = new EmptyResult();
    }
}

Я узнал, как вы можете отменить действие от выполнения, установив 'context.Result = new EmptyResult () ` здесь , но я не уверен, что это лучший способ очистить ответ и закрыть соединение.

Ответы [ 5 ]

15 голосов
/ 04 августа 2015

Установка ответа будет означать, что действие не вызывается.

public override void OnActionExecuting(HttpActionContext actionContext)    
{ 
    actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
}

Как уже говорилось в других ответах, аутентификация должна выполняться с помощью AuthorizeAttribute (Docs для Web.API *).1005 * или для MVC ).

3 голосов
/ 25 января 2018

Ответ, что @OdeyinkaOlubunmi правильно для веб-API или конкретно System.Web.Http.Filters.ActionFilterAttribute, но его нельзя использовать для System.Web.Mvc.ActionFilterAttribute.AuthorizeAttribute и переопределение AuthorizeCore - хороший способ, но если вы используете пример @ Vadim для GlobalFilter, вы получите следующую ошибку в стандартной конфигурации:

Ошибка HTTP 404.15 -Не найдено Модуль фильтрации запросов настроен на отклонение запроса, если строка запроса слишком длинная.

Это связано с тем, что по умолчанию /Login?ReturnUrl= будет добавлять новые значения до тех пор, пока строка запроса не вызовет исключение.

То, как я решил это для MVC, выглядит так:

public class DebugActionFilter : System.Web.Mvc.ActionFilterAttribute
{
  public override void OnActionExecuting(System.Web.Mvc.ActionExecutingContext actionContext)
  {
    actionContext.Result = new HttpStatusCodeResult(HttpStatusCode.Unauthorized);
    return;
  }
}
2 голосов
/ 04 марта 2011

Вы, вероятно, хотите сделать его атрибутом AuthorizeAttribute. Это автоматически установит результат как UnAuthorizedResult, плюс его преимущество будет выполняться перед любыми другими фильтрами. В качестве альтернативы вы можете установить Результат как новый HttpUnauthorizedResult

public class SignInRequiredAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        return !Acme.Web.CurrentUser != null;
    }
}
1 голос
/ 17 января 2019

с использованием .net core 2.1 вышеупомянутые решения не работали для меня, поэтому я попробовал это, и это сработало: -

 context.HttpContext.Response.StatusCode = 401;
 return;

если есть лучшие решения для .net core 2.1, я открыт для предложений

1 голос
/ 27 сентября 2013

Вы можете установить результат filterContext для страницы исключения следующим образом:

filterContext.Result = new RedirectResult("~/Error/Unauthorized");

Подробнее здесь в разделе Отмена выполнения фильтра

...