Async action filter in MVC 4
MVC does not have an async
-compatible action filter (but WebAPI does have one).
For now, I recommend you use blocking calls in OnActionExecuting
. Hopefully MVC will have a better story in the future.
Update: You can vote here for the MVC team to add async
filters.
Making an async call in an MVC 5 action filter
There is no way to (reliably) call an asynchronous method from an ASP.NET MVC 5 action filter. This has already been fixed in ASP.NET vNext, but AFAIK there are no plans to support this in MVC 5.
If you absolutely must do this in an action filter, then you must use synchronous calls (e.g., WebClient
instead of HttpClient
).
Action filter : how to call service layer and async method
I don't see where the _adminDB dependency comes from in your code, but I'm guessing that is causing the problem.
If you want to use async filters you have to implement the IAsyncActionFilter interface.
You can retrieve services from the executing context's DI container and use async methods the following way:
public class CustomAttributeFilter : ActionFilterAttribute
{
public override async Task OnActionExecutionAsync(
ActionExecutingContext context, ActionExecutionDelegate next)
{
var adminDb = filterContext.HttpContext.RequestServices.GetService<AdminDb>();
var myFlag = await adminDb.GetFlagSettingsAsync();
//..
await next();
}
}
Depending on your your needs, you can place your custom logic after the next() call as well.
See the documentation for more information.
Calling Async Methods in Action Filters in MVC 5
Yes, it's still true. Web API 2 has support for async action filters, but MVC 5 still does not. I was just personally frustrated by this not too long ago. For the time being, you will either need to run your async method as sync inside the action filter, or repeat the async code that you would have had in an action filter inside each action that requires it, which you then can run as async.
Async OnActionExecuting in ASP.NET Core's ActionFilterAttribute
Asynchronous filters work a bit differently: first execute code that must be executed before the action, call next()
for the actual logic, finally add code to be executed after the action.
public async Task OnActionExecutionAsync(ActionExecutingContext context,
ActionExecutionDelegate next)
{
// logic before action goes here
await next(); // the actual action
// logic after the action goes here
}
The documentation is here: https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/filters#implementation
How to write an action filter for all controllers
public class LogActionFilterAttribute : IActionFilter
{
public void OnActionExecuted(ActionExecutedContext filterContext)
{
Log("OnActionExecuted", filterContext.RouteData);
}
public void OnActionExecuting(ActionExecutingContext filterContext)
{
Log("OnActionExecuting", filterContext.RouteData);
}
private void Log(string methodName, RouteData routeData)
{
var controllerName = routeData.Values["controller"];
var actionName = routeData.Values["action"];
var message = String.Format("{0} controller:{1} action:{2}", methodName, controllerName, actionName);
Debug.WriteLine(message, "Action Filter Log");
}
}
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
GlobalFilters.Filters.Add(new LogActionFilterAttribute());
}
}
OnActionExecutedAsync Not available in ActionFilterAttribute in .Net core
Use OnActionExecutionAsync
, where you can invoke the next
delegate and then run your own async logic after:
public override async Task OnActionExecutionAsync(
ActionExecutingContext context, ActionExecutionDelegate next)
{
var actionExecutedContext = await next();
// .. Your awaits here.
}
The next
delegate returns the ActionExecutedContext
.
Related Topics
Piping in a File on the Command-Line Using System.Diagnostics.Process
Can't See Localhost from Uwp App
Xmlserialize a Custom Collection with an Attribute
How to Determine the True Pixel Size of My Monitor in .Net
Cookie Authentication Expiring Too Soon in ASP.NET Core
Expression of Type 'System.Int32' Cannot Be Used for Return Type 'System.Object'
How to Get a Unique Identifier for a Device Within Windows 10 Universal
How to Ignore Get-Only Properties in JSON.Net Without Using JSONignore Attributes
Why Is Double.Nan Not Equal to Itself
Removing Hidden Characters from Within Strings
Wpf: Cannot Reuse Window After It Has Been Closed
How to Have an Optional Parameter for an ASP.NET Soap Web Service