ASP.NET MVC选择了错误的控制器操作

时间:2012-02-23 12:07:51

标签: asp.net-mvc asp.net-mvc-3 controller-actions

我有一个控制器有两个具有相同名称的动作,但是一个接受一些参数。要消除它们的歧义,只接受GET请求,而另一个只接受POST请求。我还有一个HttpAjaxAttribute,用于仅对action方法强制执行A​​jax调用。由于某种原因,这个解决方案不可靠,有时候对导入操作的GET请求MVC固执地尝试选择POST / AJAX并从HttpAjaxAttribute抛出Ajax异常。我找到了a question that may be related。我认为以特定顺序附加属性(HttpGet或HttpPost,然后是HttpAjax)可以解决问题,但事实并非如此。我的网站工作了一段时间,现在它失败了。我在看似随机的时候遇到过这个问题。如何解决它?

控制器操作

[HttpGet]
public ActionResult Import()
 {
     // some code
 }

[HttpPost]
[HttpAjax]
public ActionResult Import(string country, string state, string city, ImportModel[] locations)
{
    // some code
}

HttpAjaxAttribute

/// <summary>
/// Makes the controller action that has this attribute applied accept only Ajax requests.
/// </summary>
public class HttpAjaxAttribute : ActionMethodSelectorAttribute
{
    public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)
    {
        if (!controllerContext.HttpContext.Request.IsAjaxRequest())
        {
            throw new Exception("The action " + methodInfo.Name + " can only be called via an Ajax request");
        }
        return true;
    }
}

2 个答案:

答案 0 :(得分:3)

我很确定你不应该从你的HttpAjaxAttribute中抛出异常 ,但当行动无法提供当前请求时,只需return false

/// <summary>
/// Makes the controller action that has this attribute applied accept only Ajax requests.
/// </summary>
public class HttpAjaxAttribute : ActionMethodSelectorAttribute
{
    public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)
    {
        return controllerContext.HttpContext.Request.IsAjaxRequest();
    }
}

MVC会在找到合适的行为之前尝试检查所有行动,没有什么是顽固的。您应该告诉框架,对当前请求有效的操作是否有效。最后,MVC将触及HttpGet操作并选择它。但是在此之前抛出异常,你强行停止这个过程。

答案 1 :(得分:1)

当您添加[HttpAjax]属性时,您将限制您的操作方法,或整个控制器的功能。

当遇到优雅降级时,你想检查它是否是一个AJAX请求,如果是,则返回部分视图,或JSON或你想要返回的任何内容。否则,您将必须返回整个视图。

因此我建议你不要实现HttpAjax属性,但检查你的action方法是否是AjaxRequest:

public ActionResult Foo()
{
   if(HttpContext.Request.IsAjaxRequest())
   {
       // Return partial
   }

   // Degrade gracefully

}