我们有一个ASP.NET MVC项目,其中包含多个使用相同名称的方法。为了区分它们,我们创建了一个ActionMethodSelectorAttribute,以便查看路由并确定应该使用哪种方法。这在开发中运行良好,但一旦将其部署到生产IIS 7服务器,我们就会收到此消息。
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)
该属性如下所示。
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;
}
}
现在已经使用system.webServer配置了web.config。
<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>
为什么使用内置的Web服务器可以正常工作,但在发布时出现问题?
感谢。
答案 0 :(得分:0)
这可能是一个黑暗的镜头,但这些链接可能会帮助你
Can you overload controller methods in ASP.NET MVC?
How can I avoid AmbiguousMatchException between two controller actions?
答案 1 :(得分:0)
ActionMethodSelectorBase.RunSelectionFilters将返回所有匹配的操作,因此您需要添加可能使其他属性匹配无效的其他属性。
在我的场景中,我有1个[HttpPost]和2个[HttpGet]动作,1个使用自定义ActionMethodSelectorAttribute,从默认方法中删除[HttpGet]就足以让它不被动作过滤器返回,它是非帖子时默认或我的选择器无效。