我有一个奇怪的问题。我的观点:
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
@using(Html.BeginForm())
{
<input type="submit" value="asds"/>
}
@Html.Action("Index2")
我的控制器:
public class DefaultController : Controller
{
//
// GET: /Default1/
[HttpPost]
public ActionResult Index(string t)
{
return View();
}
public ActionResult Index()
{
return View();
}
//
// GET: /Default1/
[HttpPost]
public ActionResult Index2(string t)
{
return PartialView("Index");
}
[ChildActionOnly()]
public ActionResult Index2()
{
return PartialView();
}
}
当我点击按钮[HttpPost]Index(string t)
时,执行得很好。但在此之后[HttpPost]Index2(string t)
被解雇了,这对我来说真的很奇怪,因为我发布了Index
行动的数据而不是Index2
。我的逻辑告诉我[ChildActionOnly()]ActionResult Index2()
而不是HttpPost
一个。
为什么会这样?如何在不重命名[HttpPost]Index2
操作的情况下覆盖此行为?
答案 0 :(得分:2)
这是默认行为。这是设计的。如果您无法更改POST Index2
操作名称,则可以编写自定义操作名称选择器,即使当前请求是POST请求,也会强制使用GET Index2
操作:
public class PreferGetChildActionForPostAttribute : ActionNameSelectorAttribute
{
public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo)
{
if (string.Equals("post", controllerContext.HttpContext.Request.RequestType, StringComparison.OrdinalIgnoreCase))
{
if (methodInfo.CustomAttributes.Where(x => x.AttributeType == typeof(HttpPostAttribute)).Any())
{
return false;
}
}
return controllerContext.IsChildAction;
}
}
然后用它装饰你的两个动作:
[HttpPost]
[PreferGetChildActionForPost]
public ActionResult Index2(string t)
{
return PartialView("Index");
}
[ChildActionOnly]
[PreferGetChildActionForPost]
public ActionResult Index2()
{
return PartialView();
}