I have a BaseController which is like below.
public class BaseController : Controller
{
public string BDynamicConnectionString { get; set; }
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
// Getting dynamic connectionstring
this.BDynamicConnectionString = GetDynamicConnetionString(this.BCCompanyId, this.BCCompanyIdentifier);
}
}
I have inherited this base controller in my controller as below.
public class TestController : BaseController
{
private ClassroomBL objClassroomBL;
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
this.objClassroomBL = ClassObjects.ClassroomBLObject(BDynamicConnectionString);
}
public ActionResult FetchDefaultStatuses()
{
this.objClassroomBL.FetchDefaultStatuses(145);
return View();
}
}
As it is visible I have OnActionExecuting(ActionExecutingContext filterContext) on both BaseController and TestController.
Actually Why I did it like this is I am managing many things in base controller which are needed in each controller inherited from this.
But now I need something like OnActionExecuting(ActionExecutingContext filterContext) on particular controller because I have to initialize object before calling action and object which I have to initialize it uses a property which is initialized in BaseController.
If I am adding OnActionExecuting(ActionExecutingContext filterContext) on both then first, controller which is inheriting BaseController on this event fires before the BaseController. I know this happening because of OOPS concept.
Is anything else I can add on Controller which fires after Basecontrollers OnActionExecuting but before action execution of particular controller .
Thanks!
Just use following in the first line of overrided method:
base.OnActionExecuting(filterContext)
See also base keyword.
Related
I have 2 controllers Home with
public class HomeController : Controller
{
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
// do some irrelevant stuff
base.OnActionExecuting(filterContext);
}
public ActionResult Index()
{
return View();
}
}
and Service with
public ActionResult Confirm()
{ return RedirectToAction("Index", "Home");}
And one ActionFilterAttribute with OnActionExecuting method
public class InvitationModeAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
// do some stuff
base.OnActionExecuting(filterContext);
}
}
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new InvitationModeAttribute());
}
}
When I go to localhost/Service/Confirm , OnActionExecuting is fired, but then when RedirectToAction is called, OnActionExecuting is not fired.
How can I catch this after RedirectToAction?
Thanks
Refer this For More clarity
First of all
Remove OnActionExecuting method in controller level
public class HomeController : Controller
{
[InvitationModeAttribute]
public ActionResult Index()
{
return View();
}
}
2nd Controller
public class ServiceController : Controller
{
[InvitationModeAttribute]
public ActionResult Confirm()
{
return RedirectToAction("Index", "Home");
}
}
From MSDN
Scope of Action Filters
In addition to marking individual action methods with an action
filter, you can mark a controller class as a whole with an action
filter. In that case, the filter applies to all action methods of that
controller. Additionally, if your controller derives from another
controller, the base controller might have its own action-filter
attributes. Likewise, if your controller overrides an action method
from a base controller, the method might have its own action-filter
attributes and those it inherits from the overridden action method. To
make it easier to understand how action filters work together, action
methods are grouped into scopes. A scope defines where the attribute
applies, such as whether it marks a class or a method, and whether it
marks a base class or a derived class.
I am creating a class that derive from AuthorizeAttribute class. I need to pass the parameter in my controller, where I decorate the derive class. How can I achieve that in this situation?
[SampleAuthorization]
public ActionResult GetFileContent(Guid planId)
{
}
public class PlanAuthorizationAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
// how can I use my planId to my custom plan authorizaton
base.OnAuthorization(filterContext);
}
}
You can find the values in authorizationContext.RequestContext.HttpContext or if planId is part of the route you can even find it in authorizationContext.RequestContext.RouteData.
I have an attribute on my Controller
[ABC]
MyController
The Attribute checks something but I only want to check once per page.
public class ABCAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
////Do some check
}
The OnActionExecuting fires for every element on the page. Partials etc.
How do I check to see if the filterContext is the main page and not a child resource on the page?
public class VerificationAttribute : ActionFilterAttribute
{
public VerificationAttribute ()
{
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
//We don't care about children/partials
if (filterContext.IsChildAction)
return;
}
Ignore, think I miss read your question
Is it possible to make an action filter or something that runs before the action method itself runs on the controller?
I need this to analyze a few values in the request before the action runs.
You can override OnActionExecuting method in controller class
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
//Your logic is here...
}
You could use an attribute:
public class MyFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
// Your logic here...
base.OnActionExecuting(filterContext);
}
}
And if you want to apply it to all controllers, in your Global.asax.cs:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new MyFilterAttribute());
}
protected void Application_Start()
{
// Other code removed for clarity of this example...
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
// Other code removed for clarity of this example...
}
If u don't want to use a base controller u can also add a own HttpHandler and register it in the web.config. In the BeginProcessRequest method u can analyse the values.
Out of pure curiosity, is it possible to access the current controller from a static context while it is being executed with the current HttpRequest/Action?
No, this is not possible from a static context because many different controllers could be executing at some given point of time for multiple concurrent requests.
I don't know of a way to do it statically but what I do for this while handling some session/authentication management I have all my controllers inherit from a custom BaseController class that inherits from the System.Web.Mvc.Controller class. In the Base Controller class I override the OnActionExecuted method.
public class BaseController : Controller
{
protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
//Your logic here
base.OnActionExecuted(filterContext);
}
}
public class HomeController : BaseController
{
//
// GET: /Home/
public ActionResult Index()
{
return View();
}
}