2011-02-04 2 views
1

У нас есть проект ASP.NET MVC с несколькими методами с использованием одного и того же имени. Чтобы различать их, мы создали ActionMethodSelectorAttribute, чтобы посмотреть на маршрутизацию и определить, какой метод следует использовать. Это прекрасно работает в разработке, но после его развертывания на сервере IIS 7 мы получаем это сообщение.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; 
     } 
    } 

Теперь web.config был настроен с использованием system.webServer как это.

<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> 

Любые идеи, почему это будет нормально работать с использованием встроенного веб-сервера, но при выпуске данных возникают проблемы?

Спасибо.

ответ

0

ActionMethodSelectorBase.RunSelectionFilters будет возвращать все действия, которые соответствуют так что вам нужно будет добавить дополнительные атрибуты, которые могут аннулировать соответствие другого атрибута.

В моем сценарии у меня было 1 [HttpPost] и 2 [HttpGet] действия с 1 с использованием специального ActionMethodSelectorAttribute, Удаление [HttpGet] из метода по умолчанию было достаточным, чтобы он не возвращался фильтром действий, и это было по умолчанию, когда не-сообщение или мой селектор недействительны.

Смежные вопросы