我有一个控制器有两个具有相同名称的动作,但是一个接受一些参数。要消除它们的歧义,只接受GET请求,而另一个只接受POST请求。我还有一个HttpAjaxAttribute,用于仅对action方法强制执行Ajax调用。由于某种原因,这个解决方案不可靠,有时候对导入操作的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;
}
}
答案 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
}