We have an ASP.NET MVC project with multiple methods using the same name. In order to distinguish between them we created an ActionMethodSelectorAttribute in order to look at the routing and determine which method should be used. This works fine in development but once it's deployed to the production IIS 7 server we get this message.
System.Reflection.AmbiguousMatchException: The current request for action 'Delete' on controller type 'OperationsController' is ambiguous between the following action methods:
System.Web.Mvc.ActionResult Delete(PermissionArea, PermissionPost) on type OperationsController
System.Web.Mvc.ActionResult Delete(PermissionArea, PermissionPost, PermissionEntity`1[Comment]) on type OperationsController
at System.Web.Mvc.ReflectedControllerDescriptor.FindAction(ControllerContext controllerContext, String actionName)
at System.Web.Mvc.ControllerActionInvoker.FindAction(ControllerContext controllerContext, ControllerDescriptor controllerDescriptor, String actionName)
at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
at System.Web.Mvc.Controller.ExecuteCore()
at System.Web.Mvc.MvcHandler.<>c__DisplayClass8.<BeginProcessRequest>b__4()
at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass1.<MakeVoidDelegate>b__0()
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
The attribute looks like this.
public class StrictRouteMatchingAttribute : ActionMethodSelectorAttribute
{
private List<string> ignoreList = new List<string>()
{
"action",
"controller"
};
private List<string> matchList = new List<string>();
public StrictRouteMatchingAttribute()
{
}
public StrictRouteMatchingAttribute(string[] ValuesToMatch)
{
matchList.AddRange(ValuesToMatch.Select(x => x.Trim().ToLower()));
}
public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
{
var filteredList = controllerContext.RequestContext.RouteData.Values.Keys.Where(x => !ignoreList.Contains(x.ToLower()));
var matches = filteredList.Intersect(matchList);
var extras = filteredList.Where(x => !matchList.Contains(x.ToLower()));
if (matches.Count() == matchList.Count() && extras.Count() == 0)
{
return true;
}
return false;
}
}
Now the web.config has been configured using the system.webServer like this.
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="true">
<add name="Elmah.ErrorLog" type="Elmah.ErrorLogModule, Elmah" preCondition="managedHandler" />
<!--<add name="Elmah.ErrorFilter" type="Elmah.ErrorFilterModule" preCondition="managedHandler" />-->
<!--<add name="Elmah.ErrorMail" type="Elmah.ErrorMailModule" preCondition="managedHandler" />-->
</modules>
<handlers>
<add name="dotless" type="dotless.Core.LessCssHttpHandler,dotless.Core" path="*.less" verb="*" />
<remove name="MvcHttpHandler" />
<remove name="UrlRoutingHandler" />
<add name="MvcHttpHandler" preCondition="integratedMode" verb="*" path="*.mvc" type="System.Web.Mvc.MvcHttpHandler, System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
<add name="Elmah" path="elmah.axd" verb="POST,GET,HEAD" type="Elmah.ErrorLogPageFactory, Elmah" preCondition="integratedMode" />
</handlers>
</system.webServer>
Any ideas why this would work fine using the built-in web server but have issues when published out?
Thanks.