【问题标题】:ActionMethodSelectorAttribute is not working on IIS 7ActionMethodSelectorAttribute 在 IIS 7 上不起作用
【发布时间】:2011-02-04 03:34:04
【问题描述】:

我们有一个 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;
        }
    }

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

任何想法为什么使用内置网络服务器可以正常工作,但在发布时会出现问题?

谢谢。

【问题讨论】:

    标签: c# asp.net-mvc iis-7


    【解决方案1】:

    【讨论】:

    • 谢谢。但我已经超越了开发机器上的歧义。它只是在部署后表现不同。
    【解决方案2】:

    ActionMethodSelectorBase.RunSelectionFilters 将返回所有匹配的操作,因此您需要添加可以使其他属性匹配无效的附加属性。

    在我的场景中,我有 1 个 [HttpPost] 和 2 个 [HttpGet] 动作,其中 1 个使用自定义 ActionMethodSelectorAttribute,从默认方法中删除 [HttpGet] 足以让动作过滤器不返回它,它是未发布或我的选择器无效时的默认设置。

    【讨论】:

      猜你喜欢
      • 2012-12-23
      • 2010-11-30
      • 2011-04-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多