title: Web API Help Page emitting "An item with the same key has already been added"
body: <p>I have just upgraded my web API help page to version 2.1. When I tried to open the help page, I got this error:</p>
  
  <pre><code>[ArgumentException: An item with the same key has already been added.]
  System.ThrowHelper.ThrowArgumentException(ExceptionResource resource) +52
  System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add) +10695474
  System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value) +10
  System.Web.Http.Description.ApiExplorer.TryExpandUriParameters(IHttpRoute route, HttpParsedRoute parsedRoute, ICollection`1 parameterDescriptions, String&amp; expandedRouteTemplate) +407
  System.Web.Http.Description.ApiExplorer.PopulateActionDescriptions(HttpActionDescriptor actionDescriptor, IHttpRoute route, String localPath, Collection`1 apiDescriptions) +258
  System.Web.Http.Description.ApiExplorer.ExploreDirectRoute(HttpControllerDescriptor controllerDescriptor, CandidateAction[] candidates, IHttpRoute route) +358
  System.Web.Http.Description.ApiExplorer.InitializeApiDescriptions() +410
  System.Lazy`1.CreateValue() +416
  System.Lazy`1.LazyInitValue() +152
  System.Lazy`1.get_Value() +75
  System.Web.Http.Description.ApiExplorer.get_ApiDescriptions() +40
  CobaWebApi.Areas.HelpPage.HelpPageConfigurationExtensions.GetHelpPageApiModel(HttpConfiguration config, String apiDescriptionId) in e:\SPIKES\CobaWebApi\Areas\HelpPage\HelpPageConfigurationExtensions.cs:224
  CobaWebApi.Areas.HelpPage.Controllers.HelpController.Api(String apiId) in e:\SPIKES\CobaWebApi\Areas\HelpPage\Controllers\HelpController.cs:38
  lambda_method(Closure , ControllerBase , Object[] ) +180
  System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +59
  System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +435
  System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +60
  System.Web.Mvc.Async.ActionInvocation.InvokeSynchronousActionMethod() +76
  System.Web.Mvc.Async.AsyncControllerActionInvoker.&lt;BeginInvokeSynchronousActionMethod&gt;b__39(IAsyncResult asyncResult, ActionInvocation innerInvokeState) +36
  System.Web.Mvc.Async.WrappedAsyncResult`2.CallEndDelegate(IAsyncResult asyncResult) +73
  System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +136
  System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +102
  System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +49
  System.Web.Mvc.Async.AsyncInvocationWithFilters.&lt;InvokeActionMethodFilterAsynchronouslyRecursive&gt;b__3f() +117
  System.Web.Mvc.Async.&lt;&gt;c__DisplayClass48.&lt;InvokeActionMethodFilterAsynchronouslyRecursive&gt;b__41() +323
  System.Web.Mvc.Async.&lt;&gt;c__DisplayClass33.&lt;BeginInvokeActionMethodWithFilters&gt;b__32(IAsyncResult asyncResult) +44
  System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +47
  System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +136
  System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +102
  System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +50
  System.Web.Mvc.Async.&lt;&gt;c__DisplayClass2b.&lt;BeginInvokeAction&gt;b__1c() +72
  System.Web.Mvc.Async.&lt;&gt;c__DisplayClass21.&lt;BeginInvokeAction&gt;b__1e(IAsyncResult asyncResult) +185
  System.Web.Mvc.Async.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult) +42
  System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +133
  System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +56
  System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +40
  System.Web.Mvc.Controller.&lt;BeginExecuteCore&gt;b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +34
  System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +70
  System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +139
  System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +59
  System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +40
  System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +44
  System.Web.Mvc.Controller.&lt;BeginExecute&gt;b__15(IAsyncResult asyncResult, Controller controller) +39
  System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +62
  System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +139
  System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +59
  System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +40
  System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +39
  System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +39
  System.Web.Mvc.MvcHandler.&lt;BeginProcessRequest&gt;b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +39
  System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +70
  System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +139
  System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +59
  System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +40
  System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +40
  System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +38
  System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +9628972
  System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean&amp; completedSynchronously) +155
  </code></pre>
  
  <p>I have tracked down the problem to these two controller actions:</p>
  
  <pre><code>public class MyController : ApiController
  {
      /// &lt;summary&gt;
      /// a quick brown fox
      /// &lt;/summary&gt;
      /// &lt;param name="request"&gt;&lt;/param&gt;
      /// &lt;returns&gt;&lt;/returns&gt;
      [HttpGet]
      [ResponseType(typeof(OneResponse))]
      [Route("api/stuff/{Id}")]
      public IHttpActionResult GetOne([FromUri] OneRequest request)
      {
          return Ok(new OneResponse());
      }
  
      /// &lt;summary&gt;
      /// lazy dog
      /// &lt;/summary&gt;
      /// &lt;param name="request"&gt;&lt;/param&gt;
      /// &lt;returns&gt;&lt;/returns&gt;
      [HttpGet]
      [ResponseType(typeof(ManyResponse))]
      [Route("api/stuff")]
      public IHttpActionResult GetMany([FromUri] ManyRequest request)
      {
          return Ok(new ManyResponse());
      }
  }
  </code></pre>
  
  <p>If I remove [FromUri], help page will display without error. Somehow it considers the two endpoints to be the same if I use [FromUri].</p>
  
  <p>Is there a workaround for this?</p>