开发者

ActionMethodSelectorAttribute is not working on IIS 7

开发者 https://www.devze.com 2023-02-08 06:05 出处:网络
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

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.


This might be a shot in the dark, but these links might help you

Can you overload controller methods in ASP.NET MVC?

How can I avoid AmbiguousMatchException between two controller actions?


ActionMethodSelectorBase.RunSelectionFilters will return all the actions that match so you will need to add additional attributes that can invalidate the other attribute match.

In my scenario I had 1 [HttpPost], and 2 [HttpGet] actions with 1 using a custom ActionMethodSelectorAttribute, Removing the [HttpGet] from the default method was enough to not have it returned by the action filter and it was the default when not-post or my selector was invalidated.

0

精彩评论

暂无评论...
验证码 换一张
取 消