1

我有一个控制器,它有两个同名的动作,但一个接受一些参数。为了消除歧义,一个只接受 GET 请求,而另一个只接受 POST 请求。我还有一个 HttpAjaxAttribute,它用于仅对操作方法强制执行 Ajax 调用。由于某种原因,此解决方案不可靠,有时在对 Import 操作的 GET 请求上,MVC 顽固地尝试选择 POST/AJAX 并从 HttpAjaxAttribute 引发 Ajax 异常。我发现了一个可能相关的问题。我认为以特定顺序附加属性(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;
    }
}
4

2 回答 2

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采取行动并选择它。但是通过在此之前抛出异常,您会强制停止此过程。

于 2012-02-23T12:28:50.360 回答
1

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

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

因此,我建议您不要实现 HttpAjax 属性,而是检查您的操作方法是否是 AjaxRequest:

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

   // Degrade gracefully

}
于 2012-02-23T12:40:16.790 回答