Recently I decided to remove a heap of action level filters in a controller and replace them with a single controller level filter.

Now I'm getting this error message.

Error activating LogActionFilter
More than one matching bindings are available.
Activation path:
 1) Request for LogActionFilter

Suggestions:
 1) Ensure that you have defined a binding for LogActionFilter only once.

I'm sure the error is related to action filter being bound twice, as that's what I've changed. However, when I view the documentation here I can see it specifies/does the same. So I'm really not sure what I'm doing wrong.

My sample controller

[LogAction]
public class SomeController : Controller
{
    public ActionResult SomeAction()
    { 

    }
}

My registration code

public static void RegisterFilters()
{
    Kernel.BindFilter<LogActionFilter>(FilterScope.Controller, 0)
    .WhenControllerHas<LogActionAttribute>();

    Kernel.BindFilter<LogActionFilter>(FilterScope.Action, 0)
        .WhenActionMethodHas<LogActionAttribute>();
}
有帮助吗?

解决方案

This happens if your controller and one of its actions have the LogActionAttribute at the same time.

其他提示

(I know the answer's already accepted but this is for the sake of documentation.)

In case you can only use the release version, a temporary solution is to create two subclasses and register them separately. Here's an example from my application:

public class MyAuthorizationFilter : IAuthorizationFilter
{
   /* call base ctor */
}

public class MyControllerAuthorizationFilter : MyAuthorizationFilter
{
   /* call base ctor */
}

public class MyActionAuthorizationFilter : MyAuthorizationFilter
{
}

Then setup filter bindings:

this.BindFilter<MyControllerAuthorizationFilter>(FilterScope.Controller, 0)
            .WhenControllerHas<MyAttribute>()
            .WithConstructorArgumentFromControllerAttribute<ProtectedAttribute>(/*...*/) ;

this.BindFilter<MyActionAuthorizationFilter>(FilterScope.Action, 0)
            .WhenActionMethodHas<MyAttribute>()
            .WithConstructorArgumentFromActionAttribute<ProtectedAttribute>(/*...*/) ;

Make sure to call the correct 'WithConstructorArgumentFrom[Controller/Action]Attribute method or you'll get a 'Sequence has no elements' error (I did).

Better workaround. In fact I use this in the new version too rather than have two bindings for controllers and actions.

this.BindFilter<MyFilter>(FilterScope.Global, int.MinValue)
    .When((controllerContext, actionDescriptor) =>
                                                 controllerContext
                                                .Controller
                                                .GetType()
                                                .GetCustomAttributes(typeof(MyAttribute),true)
                                                .Length > 0 
    || actionDescriptor.GetCustomAttributes(typeof(MyAttribute), true).Length > 0);
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top