Executing code before a controller's method is invoked? - c#

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.

Related

OnActionExecution on BaseController and Particular Controller

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.

Custom AuthorizeAttribute Failing to Authorize

I am unable to make my custom authorization attribute return anything but a 401 unauthorized on controller methods.
I've setup a very basic Custom Authorization Attribute:
public static void RegisterGlobalFilters(GlobalFilterCollection filters) {
filters.Add(new HandleErrorAttribute());
filters.Add(new AuthorizeAttribute());
filters.Add(new CustomAuthorizationAttribute()); //<---Custom
}
The class itself:
public class CustomAuthorizationAttribute : System.Web.Mvc.AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
return true;
}
protected override HttpValidationStatus OnCacheAuthorization(HttpContextBase httpContext)
{
return base.OnCacheAuthorization(httpContext);
}
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
base.HandleUnauthorizedRequest(filterContext);
}
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
}
}
I've decorated my controller's actions with the CustomAuthorizationAttribute:
[HttpPost]
[CustomAuthorization]
public ActionResult UploadFile(FormCollection fileUpload)
{...
Obviously I must be missing something simple because this code always results in a 401 unauthorized response.
The AuthorizeCore method breakpoint does not get hit, but occasionally OnAuthorization method does.
I'm new to MVC5. What am I missing? How do I make this authorization work based on my custom criteria?
Thanks in advance.
There appears to be a triple redundancy with your authorize attributes. You've added three authorize filters to a single controller action. Two here:
public static void RegisterGlobalFilters(GlobalFilterCollection filters) {
filters.Add(new HandleErrorAttribute());
filters.Add(new AuthorizeAttribute());
filters.Add(new CustomAuthorizationAttribute()); //<---Custom
}
... and one here:
[HttpPost]
[CustomAuthorization]
public ActionResult UploadFile(FormCollection fileUpload)
I'm guessing that the first AuthorizeAttribute (vanilla) is applied first, hits its own AuthorizeCore(), returns false and sends your context onto 401-ville.
Try removing both global filter registrations, then see if the controller action behaves as you expect.
public static void RegisterGlobalFilters(GlobalFilterCollection filters) {
filters.Add(new HandleErrorAttribute());
}

MVC ActionFilterAttribute but only on main View

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

Handle differently GET and POST during OnActionExecuting

During the OnActionExecuting method, some processing are made which could lead to a redirection to the home page.
But in Ajax POST calls, these processing will definitely fail. Calls are made by a grid from Kendo UI, so I have no control on them.
So I want this method handles in two different ways if calls are GET and POST.
I tried :
[HttpGet]
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
// Do something
}
[HttpPost]
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
// Do nothing
}
But it does work.
I can't find a Property like IsPostBack in WebFroms.
The ActionExecutingContext has a HttpContext property. From there, you can obtain the Request property, which has a HttpMethod property
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
if(filterContext.HttpContext.Request.HttpMethod == "POST")
{
// Do nothing
}
else
{
//Do Something
}
}

General handler for ASP.NET MVC queries

I need to create a general handler for all ASP.NET MVC queries. Now I use Application_BeginRequest but there come not only ASP.NET MVC queries.
The one option I see is to create a common base controller and execute my logic in its constructor. But may be there are other options?
Have you considered action filters?
You have to add ActionFilter to your controller.
In order to do this you have to create an class inherited from ActionFilterAttribute
For example:
Public Class CustomFilterAttribute
Inherits ActionFilterAttribute
End Class
Than just apply this attribute to controller:
<CustomFilter()> _
Public Class MyController
There are 4 methods in ActionFilterAttribute which can be overrided:
OnActionExecuted
OnActionExecuting
OnResultExecuted
OnResultExecuting
Override them and this code will be executed on each request to methods of your controller
idsa,
you might be able to rustle something up using this kind of approach in a base controller:
protected override void Initialize(RequestContext requestContext)
{
Lang = requestContext.RouteData.Values["lang"].ToString()
?? System.Globalization.CultureInfo.CurrentUICulture.TwoLetterISOLanguageName;
ViewData["Lang"] = Lang;
base.Initialize(requestContext);
// your custom logic here...
}
or on:
protected override void Execute(System.Web.Routing.RequestContext requestContext)
{
base.Execute(requestContext);
// intercepting code here...
}
or:
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
// one stage later intercepting code here
}
who knows mind you :)

Categories