Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

System.Web.Http.Filters.ActionFilterAttribute must be in same project as controller?

I have a System.Web.Http.ApiController-derived controller:

[LoggingFilterApi]
public class BaseController : ApiController
{
     public IHttpActionResult Ads();
}

with the filter defined as follows:

using System.Web.Http.Controllers;
using System.Web.Http.Filters;

namespace pecom.Common.Filters
{
    public class LoggingFilterApiAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(HttpActionContext ctx)
        {
            var msg = ctx.ActionDescriptor.ControllerDescriptor.ControllerType.Name + "." + ctx.ActionDescriptor.ActionName +
                "(" + ctx.Request.RequestUri.ToString();

            ILog logger = LogManager.GetLogger(ctx.ActionDescriptor.ControllerDescriptor.ControllerType);
            logger.Info(msg);
            base.OnActionExecuting(ctx);
        }
    }
}

When LoggingFilterApiAttribute.cs is part of the controller's .csproj, OnActionExecuting is called as expected. However, if LoggingFilterApiAttribute.cs is moved to a different .csproj (to facilitate code reuse), OnActionExecuting is not called as expected. Weird.

Anyone seen this? For the time being I'm duplicating filters across our projects, which is somewhat suboptimal. This is with ASP.NET MVC 5.2.

Cheers, Pete

like image 520
sming Avatar asked Mar 27 '15 15:03

sming


People also ask

Which class is used to Register a Custom filter in Web API?

You can create custom filter attributes by implementing an appropriate filter interface for which you want to create a custom filter and derive the FilterAttribute class to use that class as an attribute.

What is the use of Action filters in an MVC application?

ASP.NET MVC provides Action Filters for executing filtering logic either before or after an action method is called. Action Filters are custom attributes that provide declarative means to add pre-action and post-action behavior to the controller's action methods.

What are filters in ASP net Core?

Filters in ASP.NET Core allow code to run before or after specific stages in the request processing pipeline. Built-in filters handle tasks such as: Authorization, preventing access to resources a user isn't authorized for. Response caching, short-circuiting the request pipeline to return a cached response.

What are Action filters?

An action filter is an attribute that you can apply to a controller action -- or an entire controller -- that modifies the way in which the action is executed.


Video Answer


2 Answers

You most likely have a mismatch in Web Api 2 versions. No matter which version of MVC, your controller is a Web Api one, so you have to pay attention to Web Api related assemblies.

I'm pretty sure that, if you check the version of System.Web.Http in both your MVC project and your class library, they'll be different, and therefore the discovery mechanism is not able to find your custom filter. Just fix the problem by making them match and it should work.

One simple way to fix that is to reference the latest Web Api 2 package (Microsoft.AspNet.WebApi.Core) in your class library, and to upgrade the same package in your MVC project to make them match (or by messing with assembly redirects if you like so). If, for example, you just copied the code into the class library and then used something like Resharper to resolve the references, it might most likely have picked version 4.x of System.Web.Http from GAC, instead of version 5.x that you need here.

I tried what you did and it reproduced your same issue, and this procedure solved it.

like image 118
Wasp Avatar answered Oct 19 '22 18:10

Wasp


I managed to make it work in a few steps :

  1. Create an MVC application
  2. Create an empty class library
  3. add the MVC framework to the class library using nuget
  4. add reference to System.Web to the class Library project
  5. Copy your code in a new class of the class library
  6. Remove code related the logger for testing purpose
  7. Replace HttpActionContext ctx by ActionExecutingContext filterContext
  8. Replace ctx.Request.RequestUri.ToString() by filterContext.HttpContext.Request.Url
  9. Reference the Class library project
  10. Add the the filter to the home controller

Job done

like image 44
christophe vialatte Avatar answered Oct 19 '22 17:10

christophe vialatte