IControllerConfiguration: An item with the same key has already been added
See original GitHub issueI’m getting an error about the same key being added when trying to loop through the ApiDescriptions. My setup is pretty simple in that i have:
[Authorize]
public class BaseController : ApiController { ... }
[AllowAnonymous, MyCustomAuthorizationFilterAttribute, MyCustomIControllerConfiguration]
public abstract class BaseEntityController : BaseController { ... }
I have two controllers that inherit from these base classes that have no duplicate names or actions.
Observations:
- If both controllers inherit from the same base class there is no problem
- If both controllers inherit a different base class the error is thrown
- If (2) and I remove the MyCustomIControllerConfiguration attribute no error is thrown.
MyCustomIControllerConfiguration is as follows:
public class MyCustomIControllerConfiguration : Attribute, IControllerConfiguration
{
public void Initialize(HttpControllerSettings controllerSettings, HttpControllerDescriptor controllerDescriptor)
{
var formatter = controllerSettings.Formatters.OfType<JsonMediaTypeFormatter>().Single();
controllerSettings.Formatters.Remove(formatter);
formatter = new JsonMediaTypeFormatter
{
SerializerSettings = { ... }
};
controllerSettings.Formatters.Add(formatter);
}
}
Removing the attribute isn’t an option. It’s odd that (1) is true with the attribute considering the error. Has anyone seen this type of error before?
Stack Trace:
[ArgumentException: An item with the same key has already been added.]
System.ThrowHelper.ThrowArgumentException(ExceptionResource resource) +56
System.Collections.Generic.Dictionary2.Insert(TKey key, TValue value, Boolean add) +14763607 System.Web.Http.HttpRouteCollection.Add(String name, IHttpRoute route) +44 System.Web.Http.Routing.AttributeRoutingMapper.AddGenerationHooksForSubRoutes(HttpRouteCollection routeTable, IEnumerable
1 entries) +147
System.Web.Http.Routing.<>c__DisplayClass2.<MapAttributeRoutes>b__0(HttpConfiguration config) +149
System.Web.Http.HttpConfiguration.ApplyControllerSettings(HttpControllerSettings settings, HttpConfiguration configuration) +94
System.Web.Http.Controllers.HttpControllerDescriptor.InvokeAttributesOnControllerType(HttpControllerDescriptor controllerDescriptor, Type type) +200
System.Web.Http.Controllers.HttpControllerDescriptor.InvokeAttributesOnControllerType(HttpControllerDescriptor controllerDescriptor, Type type) +63
System.Web.Http.Controllers.HttpControllerDescriptor…ctor(HttpConfiguration configuration, String controllerName, Type controllerType) +131
Microsoft.Web.Http.Description.VersionedApiExplorer.FlattenApiVersions() +474
Microsoft.Web.Http.Description.VersionedApiExplorer.InitializeApiDescriptions() +264
System.Lazy1.CreateValue() +236 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() +31 System.Lazy
1.get_Value() +14620009
[TargetInvocationException: Exception has been thrown by the target of an invocation.]
System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) +0
System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments) +128
System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) +142
Owin.Loader.<>c__DisplayClass12.<MakeDelegate>b__b(IAppBuilder builder) +93
Owin.Loader.<>c__DisplayClass1.<LoadImplementation>b__0(IAppBuilder builder) +212
Microsoft.Owin.Host.SystemWeb.OwinAppContext.Initialize(Action1 startup) +873 Microsoft.Owin.Host.SystemWeb.OwinBuilder.Build(Action
1 startup) +51
Microsoft.Owin.Host.SystemWeb.OwinHttpModule.InitializeBlueprint() +101
System.Threading.LazyInitializer.EnsureInitializedCore(T& target, Boolean& initialized, Object& syncLock, Func`1 valueFactory) +135
Microsoft.Owin.Host.SystemWeb.OwinHttpModule.Init(HttpApplication context) +160
System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(IntPtr appContext, HttpContext context, MethodInfo[] handlers) +581
System.Web.HttpApplication.InitSpecial(HttpApplicationState state, MethodInfo[] handlers, IntPtr appContext, HttpContext context) +168
System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr appContext, HttpContext context) +414
System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr appContext) +369
[HttpException (0x80004005): Exception has been thrown by the target of an invocation.] System.Web.HttpRuntime.FirstRequestInit(HttpContext context) +532 System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context) +111 System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +714
Issue Analytics
- State:
- Created 5 years ago
- Comments:12
The fix has been published as https://www.nuget.org/packages/Microsoft.AspNet.WebApi.Versioning.ApiExplorer/1.2.1
Thanks
This also surfaced a related, but previously undetected issue. The formatters were always coming from the original configuration, but a IControllerConfiguration can modify the formatters, which yields an entirely new configuration. It’s not particular common and know one has ever reported it before, but it could happen. Interestingly, my OData version does the right thing. I suspect this was an issue in the original API Explorer code I forked from Web API. Both issues will be fixed and published soon.