I am struggeling with this peace of code:
public class MultiDatabaseAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
}
}
I want to execute the OnActionExecuting on certain ActionResults in my API. This is a method in my API:
[MultiDatabase]
public Website Get(int id)
{
return _websites.Get(id);
}
It does not work. Whatever I try, the method attribute is not called. According to the website http://www.strathweb.com/2015/06/action-filters-service-filters-type-filters-asp-net-5-mvc-6/ this should work.
According to this question I had to add the attribute to the Global.asax. Did not help too.
Who can help me?
Thanks
You are inheriting your attribute from the wrong base class. MVC and WebAPI have different objects (at least until ASP.Net Core has since merged them into one). Make sure you have the correct import in your attribute:
using System.Web.Http.Filters;
Or use the full namespace:
public class MultiDatabaseAttribute : System.Web.Http.Filters.ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
base.OnActionExecuting(actionContext);
}
}
Related
I have the following base controller
public class BaseController : Controller
{
protected override void Execute(RequestContext requestContext)
{
base.Execute(requestContext);
}
}
Implementation is
public class HomeController : BaseController { }
we upgraded from mvc3 to mvc5 , in mvc5 this method is not getting called what needs to be done here ?
It's not entirely clear what your after but here's a few questions. Are your normal controllers inheriting your BaseController?
public class MyController : BaseController
I don't see what this line is meant to do....
var global = requestContext.HttpContext.Request.QueryString["global"] == null ? true : false;
You set the value then don't do anything with it. Are you meaning to store this value in the base controller so that you can access it from all your other controllers?
And surely if global is missing from the querystring then it should be false and not true.
public class BaseController : Controller
{
public bool isGlobal { get; private set; }
protected override void Execute(RequestContext requestContext)
{
this.isGlobal = requestContext.HttpContext.Request.QueryString["global"] == null ? false : true;
base.Execute(requestContext);
}
}
The title of this question led me here, but it's not really the same problem I was experiencing (i.e. the overridden Execute method in a base controller class not being called in an MVC 4/5 web site).
If that is the problem you are having too, this is the solution I found. It appears the way in which these methods are called has changed with the introduction of Async support. Instead of overriding the Execute method you should override the OnActionExecuted method instead.
protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
}
public class CustomAuthorizeAttribute : AuthorizationFilterAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
return true;// if my current user is authorised
}
}
Above is my CustomAuthorizeAttribute Class
and
[CustomAuthorize] // both [CustomAuthorize] and [CustomAuthorizeAttribute ] I tried
public class ProfileController : ApiController
{
//My Code..
}
When I'm calling
http://localhost:1142/api/Profile
It is not firing CustomAuthorizeAttribute
More over My FilterConfig class is look like below
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new CustomAuthorizeAttribute());
}
}
Please help if I miss something.
Looks like you are using an MVC filter instead of a Web API filter. It can be detected in the sample because it uses HttpContextBase. Instead use the filter from the System.Web.Http.Filters namespace.
You need to override OnAuthorization or OnAuthorizationAsync on the Web API filter.
You don't need to register a global filter and decorate your controller with it. Registering it will make it run for all controllers.
Web API filter code:
https://github.com/aspnetwebstack/aspnetwebstack/blob/master/src/System.Web.Http/Filters/AuthorizationFilterAttribute.cs
YOur custom attribute should inherit from System.Web.Http.Filters.AuthorizationFilterAttribute
and it should look like this
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
public class CustomAuthorizeAttribute : System.Web.Http.Filters.AuthorizationFilterAttribute
{
public override bool AllowMultiple
{
get { return false; }
}
public override void OnAuthorization(HttpActionContext actionContext)
{
//Perform your logic here
base.OnAuthorization(actionContext);
}
}
Try with this.
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
protected override bool IsAuthorized(System.Web.Http.Controllers.HttpActionContext actionContext)
{
return true;
}
}
To add onto the other answers that have you inherit from System.Web.Http.Filters.AuthorizationFilterAttribute, I put this into my OnAuthorization method to make sure the user was logged in:
if (!actionContext.RequestContext.Principal.Identity.IsAuthenticated)
{
// or whatever sort you want to do to end the execution of the request
throw new HttpException(403, "Forbidden");
}
This thing is killing me. Basically what I have is the custom ActionFilter (Class which Inherits from ActionFilterAttribute and implements IActionFilter). it looks like this
public class ValidationFilterAttribute : ActionFilterAttribute, IActionFilter
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
// do some stuff here
}
}
this is what FilterConfig looks like
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
filters.Add(new ValidationFilterAttribute());
}
}
But whenever I start the project there is an exception saying following
The given filter instance must implement one or more of the following filter interfaces: IAuthorizationFilter, IActionFilter, IResultFilter, IExceptionFilter.
But obviously the ValidationFilterAttribute implements one of those interfaces. Am I missing something very basic here? I can't figure out what is wrong.
Prefix your base class with System.Web.Mvc, I have a "hunch" you may be using System.Web.Http.Filters.ActionFilterAttribute instead.
So then you would have to override
OnActionExecuting(ActionExecutingContext filterContext)
And things will be OK.
And as you can see, ActionFilterAttribute implements IActionFilter already, so you don't need to specify it.
As far as I know, you don't need the IActionFilter declaration.
ActionFilterAttribute already implements IActionFilter
But I don't know if this is the cause of the error message. Could you try removing it?
Check this also: http://forums.asp.net/t/1835666.aspx
[Serializable] public class RedirectingAction : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context) { base.OnActionExecuting(context);
}
after that use this attributes in your controller like below
[RedirectingAction]
public class HomeController : BaseController { }
custom action filter example by www.jkittraining.com
www.jkittraining.com/course/asp-net-mvc-training/
I'm having some problem with my custom AuthorizeAttribute
public class ExplicitAuthorizeAttribute : AuthorizeAttribute
{
private readonly MembershipUserRole[] _acceptedRoles;
public ExplicitAuthorizeAttribute()
{
}
public ExplicitAuthorizeAttribute(params MembershipUserRole[] acceptedRoles)
{
_acceptedRoles = acceptedRoles;
}
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
//Validation ...
}
}
I use it like this:
[ExplicitAuthorize[(MembershipUserRole.Admin, MembershipUserRole.SuperAdmin)]
It works perfectly for HttpGet and HttpPost to validate my controllers and methods.
But when I use it in a ApiController and make ajax calls, AuthorizeCore isn't running and I got a security breach. :/
My enum looks like this
[Flags]
public enum MembershipUserRole
{
Admin= 1,
SuperAdmin = 2
}
Does anyone know why my AuthorizeCore isn't validating in this context?
By the way If I use
[Authorized(Roles ="Admin, SuperAdmin")]
It's validates perfectly, but I'd like to have Stronly Typed Roles,that's why I'm using enums.
You have derived from the wrong class: System.Web.Mvc.AuthorizeAttribute whereas for a Web API controller you should derive from System.Web.Http.AuthorizeAttribute.
Don't forget that ASP.NET MVC and ASP.NET Web API are 2 completely different frameworks and even if they share some common principles and names, the corresponding classes are located in 2 completely different namespaces.
So what you have done is decorate an ASP.NET Web API action with an AuthorizeAttribute that it doesn't know anything about.
If you want to make authorization in ASP.NET Web API make sure you have derived from the correct attribute:
public class ExplicitAuthorizeAttribute : System.Web.Http.AuthorizeAttribute
{
private readonly MembershipUserRole[] _acceptedRoles;
public ExplicitAuthorizeAttribute()
{
}
public ExplicitAuthorizeAttribute(params MembershipUserRole[] acceptedRoles)
{
_acceptedRoles = acceptedRoles;
}
protected override bool IsAuthorized(HttpActionContext actionContext)
{
//Validation ...
}
}
I've found a few questions on this, but they tend to point to the exact documentation I'm following... but it's still not working.
I'm building a fairly simple ASP.NET MVC 4 site, and the plan is to use ActionFilterAttribute-based logging. I have a DataAccessProvider class which opens transactions with the database and provides unit-of-work instances, and I'm trying to inject it into the filter attribute.
The documentation says that it's enough to just call RegisterFilterProvider(), and ensure that the relevant types are registered. It specifically says that there is no need to register the attribute, but I've tried both with and without. My code currently looks something like this:
var builder = new ContainerBuilder();
builder.RegisterControllers(Assembly.GetExecutingAssembly());
builder.Register(x => new EntityAccessProvider())
.As<IDataAccessProvider>()
.InstancePerHttpRequest();
builder.RegisterType<DebugLogAttribute>().PropertiesAutowired();
// ^ I've tried it with and without this line
builder.RegisterFilterProvider();
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
The example in the docs then just places a property on the filter, so I've done the same:
public class DebugLogAttribute : ActionFilterAttribute
{
private IDataAccessProvider DataAccess { get; set; }
public override void OnActionExecuting(ActionExecutingContext filterContext) { ... }
public override void OnActionExecuted(ActionExecutedContext filterContext) { ... }
}
The docs say that's all is required - not even a constructor to inject into; it's done by property injection. When I run this code, however, The DataAccess property is always null; Autofac seems to ignore it. I know the registration works properly because it's correctly injecting EntityAccessProvider into my controllers, but it's not working for attributes. What am I missing?
Your property of type IDataAccessProvider has to be public for injection to work. You can still mark DebugLogAttribute, IDataAccessProvider and it's implementation as internal if you prefer.
[DebugLogAttribute]
public class HOmeController : Controller
{
public ActionResult Index()
{
return View();
}
}
internal class DebugLogAttribute : ActionFilterAttribute
{
public IDataAccessProvider DataAccess { get; set; }
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
Debugger.Break();
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
Debugger.Break();
}
}
internal interface IDataAccessProvider {}
internal class DataAccessProvider:IDataAccessProvider {}
I've been having the same issue in asp dotnet core but the current solution (making it public) doesn't seem to work. What I find odd is that the comment below is regarding a web-api but I'm using a normal ASP.NET Core MVC (MVC6). So if anyone has the same problem, try out the solution below.
https://docs.autofac.org/en/latest/integration/webapi.html#standard-web-api-filter-attributes-are-singletons
Unlike the filter provider in MVC, the one in Web API does not allow you to specify that the filter instances should not be cached. This means that all filter attributes in Web API are effectively singleton instances that exist for the entire lifetime of the application.
public override async Task OnActionExecutionAsync(
ActionExecutingContext context,
ActionExecutionDelegate next)
{
MyService = context.HttpContext.
RequestServices.GetService(typeof(IMyService)) as IMyService;
}