कार्रवाई फ़िल्टर विशेषता से पुनर्निर्देशित करें


139

क्या एक में एक रीडायरेक्ट करने के लिए सबसे अच्छा तरीका है ActionFilterAttribute। मेरे पास एक ActionFilterAttributeबुलाया गया है IsAuthenticatedAttributeFilterऔर जिसने एक सत्र चर के मूल्य की जांच की है। यदि चर गलत है, तो मैं चाहता हूं कि एप्लिकेशन लॉगिन पृष्ठ पर रीडायरेक्ट करे। मैं रूट नाम का उपयोग करके पुनर्निर्देशित करना पसंद करूंगा, SystemLoginहालांकि इस बिंदु पर कोई भी पुनर्निर्देशित विधि ठीक होगी।


जवाबों:


187

FilterContext.Result सेट करें

मार्ग के नाम के साथ:

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

आप कुछ ऐसा भी कर सकते हैं:

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

यदि आप उपयोग करना चाहते हैं RedirectToAction:

आप किसी सार्वजनिक कर सकता है RedirectToActionविधि अपने नियंत्रक पर ( इसके आधार नियंत्रक पर अधिमानतः ) कि बस की रक्षा की कॉल RedirectToActionसे System.Web.Mvc.Controller। इस विधि को जोड़ने से फ़िल्टर से आपके लिए एक सार्वजनिक कॉल की अनुमति मिलती है RedirectToAction

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

तब आपका फ़िल्टर कुछ इस तरह दिखाई देगा:

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

8
यह काम करता है, लेकिन क्या पुनर्निर्देशन विधि उपलब्ध नहीं होनी चाहिए?
बेन मिल्स

@BenMills वहाँ है, हालांकि, यह protectedतो आप फिल्टर से इसे तक पहुँच नहीं होता है।
जेम्स

10
मेरा प्रश्न अब यह है कि Microsoft ने यह फ़िल्टर बनाने का निर्णय क्यों लिया, protectedकुछ उचित स्पष्टीकरण होना चाहिए? मुझे RedirectToActionयह समझ में न आने की गंदी पुनर्निर्देशित करने में बहुत गंदी लग रही है कि पहली बार में इसका एनकाउंटर क्यों किया गया।
मैथ्यू मार्लिन

2
@MatthewMarlin - किसी कार्रवाई को पुनर्निर्देशित करने के लिए सही उत्तर के लिए साइकुर द्वारा उत्तर देखें। आप सही हैं कि आपको किसी एक्शन फ़िल्टर से सीधे नियंत्रक नहीं कहा जाना चाहिए - यह तंग युग्मन की परिभाषा है।
नाइटऑवल 88

1
@Akbari क्या आपने विशेषताओं के आदेश गुण सेट करने का प्रयास किया है? इसके अलावा FilterScope wil प्रभाव निष्पादन आदेश।
सीआरएस

79

वैकल्पिक रूप से पुनर्निर्देशित करने के लिए, यदि यह आपका अपना कोड कह रहा है, तो आप इसका उपयोग कर सकते हैं:

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

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

यह एक शुद्ध पुनर्निर्देशन नहीं है, लेकिन अनावश्यक ओवरहेड के बिना एक समान परिणाम देता है।


आपने मेरी मदद की। धन्यवाद!
एडगर सालजार

25
ध्यान दें कि आपको actionContext.Result.ExecuteResultअपने एक्शन फ़िल्टर के भीतर से कॉल नहीं करना चाहिए - एमवीसी स्वचालित रूप से एक्शन फ़िल्टर के चलने के बाद करेगा (बशर्ते actionContext.Resultकि यह अशक्त न हो)।
NightOwl888

12

मैं MVC4 का उपयोग कर रहा हूं, मैंने प्राधिकरण ब्रीच पर एक कस्टम html स्क्रीन को पुनर्निर्देशित करने के लिए निम्नलिखित दृष्टिकोण का उपयोग किया।

बढ़ाएँ AuthorizeAttributeकहते CutomAuthorizer ओवरराइड OnAuthorizationऔरHandleUnauthorizedRequest

रजिस्टर CustomAuthorizerमें RegisterGlobalFilters

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{

    filters.Add(new CustomAuthorizer());
}

unAuthorizedएक्सेस कॉल की पहचान HandleUnauthorizedRequestकरने और संबंधित कंट्रोलर एक्शन को रीडायरेक्ट करने के लिए जैसा कि नीचे दिखाया गया है।


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

ऐसा लगता है, जैसे आप को फिर से लागू, या संभवतः का विस्तार करना चाहते AuthorizeAttribute। यदि हां, तो आपको यह सुनिश्चित करना चाहिए कि आपको वह विरासत में मिला है, और नहींActionFilterAttribute ASP.NET MVC को आपके लिए अधिक काम करने देने के लिए आपको ।

इसके अलावा, आप यह सुनिश्चित करना चाहते हैं कि आप कार्य विधि में कोई वास्तविक कार्य करने से पहले यह सुनिश्चित कर लें - अन्यथा, लॉग इन और केवल एक ही अंतर है कि आप वह पेज क्या काम करते हैं।

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);
    }
}

एक अच्छा नहीं है सवाल एक साथ जवाब अधिक जानकारी के इतने पर यहाँ के साथ।


5

निम्नलिखित स्निपेट आज़माएं, यह बहुत स्पष्ट होना चाहिए:

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);
  }
}

यह मेरे लिए काम करता है, मुझे क्वेरी स्ट्रिंग मानों की जांच करनी थी यदि कोई भी उपयोगकर्ता क्वेरी स्ट्रिंग मानों को बदलने की कोशिश करता है और डेटा तक पहुंचने की कोशिश करता है जो कि उसे अधिकृत नहीं है, तो मैं उसे अनधिकृत संदेश पृष्ठ पर पुनर्निर्देशित कर रहा हूं, ActionFilterAttribute का उपयोग करके।
समीर

3

यहाँ एक समाधान है जो अजाक्स अनुरोध का उपयोग करने पर भी ध्यान में रखता है।

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

यह मेरे लिए काम करता है (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

आप अपने कंट्रोलर को इनहेरिट कर सकते हैं और फिर इसे अपने एक्शन फ़िल्टर के अंदर इस्तेमाल कर सकते हैं

अपने ActionFilterAttribute वर्ग के अंदर:

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

अपने बेस कंट्रोलर के अंदर:

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

विपक्ष। यह "MyController" वर्ग से विरासत में सभी नियंत्रकों को बदलने के लिए है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.