Could base class attribute be triggered first? - c#

It looks like in .NET base class attributes are triggered after Attributes that belong to inherited classes. Seems off to me or am I doing something wrong ?.
All classes in my application inherit from a base class with [AuthorizationAttribute] but only some classes have [LoggingAttribute].
When I'm accessing a method in HomeController, why does my [LoggingAttribute] gets hit before Authorization and how can I trigger base class authorization attribute first and Logging second ?
[AuthorizationAttribute]
public class BaseController
{
//....class methods
}
[LoggingAttribute]
public class HomeController: BaseController
{
//....class methods
}
Attributes:
public class AuthorizationAttribute : ActionFilterAttribute
{
//...API token gets parsed into Id/Pw
}
public class LoggingAttribute: ActionFilterAttribute
{
//...Logging record saved with Id/pw established above
}

For this specific case, since it is about authorization, make sure to derive your custom AuthorizationAttribute from AuthorizeAttribute or implement IAuthorizationFilter.
Authorization filters get executed prior to action filter attributes.
This guarantees that controller action methods only get executed when authorized.

Related

How to make AuthorizeAttribute in parent controller execute before AuthorizeAttribute in derived controller

Suppose I have this FirstExecuteAttribute:AuthorizeAttribute in the parent controller
[FirstExecute]
public abstract class ParentController: ApiController
And then this SecondExecuteAttribute:AuthorizeAttribute in the derived controller
[SecondExecute]
public class DerivedController: ParentController
I thought this hierachy structure would ensure that FirstExecute execute before SecondExecute but not really. What is the best way to achieve what I want then?
This is a .NET Framework Web API project.

Extend Repository Class C# specific to Entity

I currently have a entity framework repository class that has been based upon the below code I found online.
https://gist.github.com/ashrafeme/060f7773e25903ced986804ee7276f5f
This works fine, however, I'd like to create additional methods that perform specific functions for specific entities. For example, if I had a blog post that needed to filter by Post Type, I could write in my controller
SqlRepository<Blog, MyContext> blogPostRepo = new SqlRepository<Blog, MyContext>(dbContext);
LinkedList<Blog> blogPosts = (LinkedList<Blog>)blogPostRepo.Set<Blog>().Where(p => p.PostType.Id.Equals(2));
However Ideally I would like to just extend the Base SqlRepository Class to create a BlogPostRepository to try and keep the code clean. I'm getting stuck at the minute with the class signatures in my BlogPostRepository. How would I write a class that extends the below base class/
public class SqlRepository<TEntity, TContext> : IRepository<TEntity>, IDisposable
where TEntity : class
where TContext : DbContext
{
enter code here
Create class like:
public class BlogRepository : SqlRepository<Blog, MyContext>
Add a constructor to the derived class with necessary parameters that calls the constructor of the base class (Ref : Link)

How to create "filters" for class' methods?

With ASP.NET I have created a few filters extending both ExceptionFilterAttribute and ActionFilterAttribute. With ActionFilterAttribute I can execute actions before or after the method's execution. I'd like to mimic that behavior on my class. I have a base class called BaseService and whenever a method from this class is invoked I'd like to check if it contains an attribute and if it does execute that. For instance, on my derived classes I have methods like:
public void DoSomething()
{
LoggedUser.RequireAnyRole<RoleX, RoleY>("DoSomething");
// code here
}
public void DoSomething2()
{
LoggedUser.RequireRole<RoleX>("DoSomething2");
// code here
}
Instead of writing LoggedUser.RequireRole... I'd like it to be an attribute. That way I'd just add an attribute on top of DoSomething2: [RequireRole(Roles.X)].
Is this possible? If so, what is the best approach? I was reading something related to callmember, but I'm not sure that's the way to do it. I checked https://github.com/ASP-NET-MVC/aspnetwebstack for its implementation but I think I didn't know how to search for it since I didn't find anything...

Inheriting Route attribute messes up already existing actions in Web API

I am trying to inherit Route attributes from a base Controller exactly according to this. Though it seems to work correctly, but it messes up the previously working actions.
Below are a minimal example of my base and child controllers.
[RoutePrefix("api/{controller}")]
public class MyController<TEntity, TDto>: ApiController{
[HttpGet]
public IEnumerable<TDto> All(){
...
}
[HttpGet, Route("lookup")]
public virtual IEnumerable<TDto> LookupData(){
...
}
}
[RoutePrefix("api/entity")]
public class EntityController : MyController<Entity, DTO>
{
}
After implementing the route attribute inheritance, the api/entity/lookup action works but in case of api/entity (for All), ActionSelector returns 2 actions, both All, and LookupData, thus causing error.
I am not sure why it is selecting an action with Route attribute even in case of a regular route. What I should do differently? Or is there any robust way to write a ActionSelector for this problem?
Try adding empty [Route] to All method:
[HttpGet]
[Route]
public IEnumerable<TDto> All(){
...
}

Removing an inherited Attribute in .net

I got a ASP.NET MVC controller like this
[Authorize]
public class ObjectController : Controller
{
public ObjectController(IDataService dataService)
{
DataService = dataService;
}
public IDataService DataService { get;set;}
}
The Authorize attribute is defined as "Inherited=true" in the framework. So when i make the next controller:
public class DemoObjectController : ObjectController
{
public DemoObjectController(IDataService dataService)
: base (dataService)
{
DataService = new DemoDataService(DataService);
}
}
It gets the authorize attribute, but i don't want it here. I want the Demo Object controller to be available to everyone, cause it just uses fake data.
I guess I'll implement my own Authorize attribute that don't get inherited, for i can't find any way to remove the attribute from the inherited class.
Since it is marked as inherited, there isn't much you can do in this case (since you don't control the code that is checking for the attribute via reflection). Implementing your own attribute seems the most practical option.
With MVC you can also often achieve the same functionality with overrides (the On* methods), which might be worth looking into.
If a base type requires authorization then all child types ought to require authorization as well. I think that you ought to inherit from a different type but a workaround would be to declare your own AthorizeAttribute that works for this particular instance.

Categories