Eylem Filtresi Özelliğinden Yeniden Yönlendir


139

İçinde yönlendirme yapmanın en iyi yolu nedir ActionFilterAttribute? Ben bir ActionFilterAttributeçağrı var IsAuthenticatedAttributeFilterve bir oturum değişkeni değerini kontrol etti. Değişken yanlışsa, uygulamanın giriş sayfasına yönlendirmesini istiyorum. SystemLoginAncak bu noktada herhangi bir yönlendirme yöntemi iyi olurdu yol adını kullanarak yeniden yönlendirmeyi tercih ediyorum .


Yanıtlar:


187

FilterContext.Result öğesini ayarlayın

Rota adı ile:

filterContext.Result = new RedirectToRouteResult("SystemLogin", routeValues);

Ayrıca şöyle bir şey yapabilirsiniz:

filterContext.Result = new ViewResult
{
    ViewName = SharedViews.SessionLost,
    ViewData = filterContext.Controller.ViewData
};

Kullanmak istiyorsanız RedirectToAction:

Bir kamu yapabiliriz RedirectToActionKumandanızda (yöntemini tercih onun ana kontrolör üzerindeki basitçe korunmuş aramaları olduğunu) RedirectToActionden System.Web.Mvc.Controller. Bu yöntemi ekleme için bir kamu arama için izin verir SİZİN RedirectToAction filtresinden.

public new RedirectToRouteResult RedirectToAction(string action, string controller)
{
    return base.RedirectToAction(action, controller);
}

Ardından filtreniz şöyle görünecektir:

public override void OnActionExecuting(ActionExecutingContext filterContext)
{
    var controller = (SomeControllerBase) filterContext.Controller;
    filterContext.Result = controller.RedirectToAction("index", "home");
}

8
Bu çalışıyor, ancak kullanılabilir bir RedirectToAction yöntemi olmamalı mı?
Ben Mills

@BenMills var, bu protectedyüzden filtreden ona erişemezsiniz.
James

10
Şimdi sorum şu: Microsoft bu filtreyi neden protectedmakul bir açıklama olması gerektiğine karar verdi ? RedirectToActionİlk etapta neden kapsüllendiğini anlamadan bu erişilebilirliği yeniden tanımlarken çok kirli hissediyorum .
Matthew Marlin

2
@MatthewMarlin - Bir eyleme yönlendirmek için doğru cevap için Syakur'un cevabına bakın. Bir denetleyiciyi doğrudan bir eylem filtresinden çağırmamanız gerektiği konusunda haklısınız - yani sıkı bağlantı tanımı.
NightOwl888

1
@Akbari, özniteliklerin Order özelliğini ayarlamayı denediniz mi? Ayrıca FilterScope yürütme sırasını etkiler.
CRice

79

Alternatif olarak, yeniden yönlendirmeye, kendi kodunuzu çağırıyorsa, bunu kullanabilirsiniz:

actionContext.Result = new RedirectToRouteResult(
    new RouteValueDictionary(new { controller = "Home", action = "Error" })
);

actionContext.Result.ExecuteResult(actionContext.Controller.ControllerContext);

Saf bir yönlendirme değildir, ancak gereksiz ek yük olmadan benzer bir sonuç verir.


Bana yardım ettin. Teşekkürler!
Edgar Salazar

25
actionContext.Result.ExecuteResultEylem filtrenizden aramamanız gerektiğini unutmayın - MVC bunu eylem filtresi çalıştıktan sonra otomatik olarak yapacaktır ( actionContext.Resultboş değilse).
NightOwl888

12

MVC4 kullanıyorum, yetkilendirme ihlali üzerine özel bir html ekranını yönlendirmek için aşağıdaki yaklaşımı kullandım.

Genişletme AuthorizeAttributedediklerini CutomAuthorizer geçersiz kıl OnAuthorizationveHandleUnauthorizedRequest

Kayıt CustomAuthorizeriçinde RegisterGlobalFilters.

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{

    filters.Add(new CustomAuthorizer());
}

belirlenmesi üzerine unAuthorizederişim çağrıyı HandleUnauthorizedRequestaşağıda gösterildiği gibi, ilgili denetçi eylemine ve yönlendirme.


public class CustomAuthorizer : AuthorizeAttribute
{

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        bool isAuthorized = IsAuthorized(filterContext); // check authorization
        base.OnAuthorization(filterContext);
        if (!isAuthorized && !filterContext.ActionDescriptor.ActionName.Equals("Unauthorized", StringComparison.InvariantCultureIgnoreCase)
            && !filterContext.ActionDescriptor.ControllerDescriptor.ControllerName.Equals("LogOn", StringComparison.InvariantCultureIgnoreCase))
        {

            HandleUnauthorizedRequest(filterContext);

        }
    }

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        filterContext.Result =
       new RedirectToRouteResult(
           new RouteValueDictionary{{ "controller", "LogOn" },
                                          { "action", "Unauthorized" }

                                         });

    }
}

9

Yeniden uygulamak veya muhtemelen genişletmek istediğiniz gibi geliyor AuthorizeAttribute. Eğer öyleyse, ActionFilterAttributeASP.NET MVC'nin sizin için daha fazla iş yapmasına izin vermek için değil miras aldığınızdan emin olmalısınız.

Ayrıca, eylem yöntemindeki gerçek işlerden herhangi birini yapmadan önce yetkilendirdiğinizden emin olmak istersiniz - aksi takdirde, oturum açıp açılmamış arasındaki tek fark, iş bittiğinde gördüğünüz sayfa olacaktır.

public class CustomAuthorizeAttribute : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        // Do whatever checking you need here

        // If you want the base check as well (against users/roles) call
        base.OnAuthorization(filterContext);
    }
}

Burada SO hakkında daha fazla ayrıntı içeren bir cevapla iyi bir soru var .


5

Aşağıdaki snippet'i deneyin, oldukça açık olmalıdır:

public class AuthorizeActionFilterAttribute : ActionFilterAttribute
{
  public override void OnActionExecuting(FilterExecutingContext filterContext)
  {
    HttpSessionStateBase session = filterContext.HttpContext.Session;
    Controller controller = filterContext.Controller as Controller;

    if (controller != null)
    {
      if (session["Login"] == null)
      {
        filterContext.Cancel = true;
        controller.HttpContext.Response.Redirect("./Login");
      }
    }

    base.OnActionExecuting(filterContext);
  }
}

Bu benim için çalıştı, herhangi bir kullanıcı sorgu dizesi değerlerini değiştirmeye çalışırsa ve ActionFilterAttribute kullanarak yetkisiz ileti sayfasına yönlendirdiğimden ona izin verilmeyen verilere erişmeye çalışırsa sorgu dizesi değerlerini kontrol etmek zorunda kaldım.
Sameer

3

Ajax istekleri kullanıyorsanız, bunu da dikkate alan bir çözüm.

using System;
using System.Web.Mvc;
using System.Web.Routing;

namespace YourNamespace{        
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
    public class AuthorizeCustom : ActionFilterAttribute {
        public override void OnActionExecuting(ActionExecutingContext context) {
            if (YourAuthorizationCheckGoesHere) {               
                string area = "";// leave empty if not using area's
                string controller = "ControllerName";
                string action = "ActionName";
                var urlHelper = new UrlHelper(context.RequestContext);                  
                if (context.HttpContext.Request.IsAjaxRequest()){ // Check if Ajax
                    if(area == string.Empty)
                        context.HttpContext.Response.Write($"<script>window.location.reload('{urlHelper.Content(System.IO.Path.Combine(controller, action))}');</script>");
                    else
                        context.HttpContext.Response.Write($"<script>window.location.reload('{urlHelper.Content(System.IO.Path.Combine(area, controller, action))}');</script>");
                } else   // Non Ajax Request                      
                    context.Result = new RedirectToRouteResult(new RouteValueDictionary( new{ area, controller, action }));             
            }
            base.OnActionExecuting(context);
        }
    }
}

1

Bu benim için çalışıyor (asp.net core 2.1)

using JustRide.Web.Controllers;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;

namespace MyProject.Web.Filters
{
    public class IsAuthenticatedAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            if (context.HttpContext.User.Identity.IsAuthenticated)
                context.Result = new RedirectToActionResult(nameof(AccountController.Index), "Account", null);
        }
    }
}



[AllowAnonymous, IsAuthenticated]
public IActionResult Index()
{
    return View();
}

0

kontrol cihazınızı devralabilir ve ardından eylem filtrenizin içinde kullanabilirsiniz

ActionFilterAttribute sınıfınızın içinde:

   if( filterContext.Controller is MyController )
      if(filterContext.HttpContext.Session["login"] == null)
           (filterContext.Controller as MyController).RedirectToAction("Login");

baz denetleyicinizin içinde:

public class MyController : Controller 
{
    public void  RedirectToAction(string actionName) { 
        base.RedirectToAction(actionName); 
    }
}

Eksileri. Bu "MyController" sınıfından devralmak için tüm denetleyicileri değiştirmek için

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.