【问题标题】:Html.Action does not render actionmethods annotated with [HttpPost]Html.Action 不呈现使用 [HttpPost] 注释的操作方法
【发布时间】:2012-01-06 10:03:20
【问题描述】:

我的控制器上有以下方法:

  [HttpPost]
  public ActionResult UnplannedCourses(int studentId)
  {
     var model = CreateUnplannedCourseModel(studentId);
     return View("UnplannedCourses", model);
  }

在我看来,我尝试:

  <div class="unplannedcourses">
  @Html.Action("UnplannedCourses", "Student", new { studentId = Model.StudentId })
  </div>

但这会产生错误:在控制器“Digidos.MVCUI.Controllers.StudentController”上找不到公共操作方法“UnplannedCourses”。

如果我将 [HttpPost] 留在外面,那么它可以工作,但我稍后会再次从 javascript 中使用该操作,所以我希望只有 POST 可用。

有什么办法吗?

【问题讨论】:

  • 你为什么不把它设置为GET,然后通过你的JavaScript代码和GET调用它呢?
  • 我所有的交流都是通过 POST 进行的,所以我想继续这种做法。
  • John Html.Actionlink 不使用任何东西(get/post) 来传递控制权,并且您使用 [httppost] 装饰了您的操作。
  • @Kannas:我从来没有提到过 Html.ActionLink...

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


【解决方案1】:

我认为我最好的选择是基于 MVC 源的新属性:

public class ChildishAttribute : ActionMethodSelectorAttribute
{
   private static readonly AcceptVerbsAttribute _innerAttribute = new AcceptVerbsAttribute(HttpVerbs.Post);
   public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)
   {
      var isPost = _innerAttribute.IsValidForRequest(controllerContext, methodInfo);
      var isChildAction = controllerContext.IsChildAction;
      var isAjax = controllerContext.RequestContext.HttpContext.Request.IsAjaxRequest();

      return isChildAction || (isAjax && isPost);
  }
}

[Childish]
public ActionResult UnplannedCourses(int studentId)
{
   var model = CreateUnplannedCourseModel(studentId);
   return View("UnplannedCourses", model);
}

【讨论】:

  • 我喜欢你的解决方案,它又好又干净!
  • 谢谢,我在使用内置属性时遇到了完全相同的问题。
【解决方案2】:

Html.Action 是一个 html 辅助方法,并使用 Http GET 而不是 POST 调用您的控制器操作。

Html.Action 是一个 html 辅助方法,它调用您的控制器操作,该操作接受 GET 请求。

编辑:

如果您的目的是防止通过浏览器查看该页面,请按如下方式实现ChildActionOnly 属性:

  [ChildActionOnly]
  public ActionResult UnplannedCourses(int studentId)
  {
     var model = CreateUnplannedCourseModel(studentId);
     return View("UnplannedCourses", model);
  }

编辑:

如果您想通过 Http POST 通过 JavaScript 调用您的操作,请查看以下帖子:

Working With JQuery Ajax API on ASP.NET MVC 3.0

【讨论】:

  • 实际上,Html.Action 助手没有使用任何 HTTP 请求来调用操作,因此谈论诸如 GET 和 POST 之类的动词是不正确的。他还提到他想从 jQuery 调用操作,所以用[ChildActionOnly] 属性装饰它可以防止这种情况发生。
  • [ChildActionOnly] 不起作用,正如 Darin 所说,它阻止了我使用 Ajax。我现在最好的选择是两个名称不同的相同方法。一个带有 [HttpPost],另一个带有 [ChildActionOnly]。希望有人有更好的解决方案。
  • @JohnLandheer 当您查看 Html Action 帮助程序的源代码时,您会看到它以当前的 HttpContext 作为您的页面调用子操作:htmlHelper.ViewContext.HttpContext。如果你愿意,你可以自己写,它不是太难,但也不是微不足道的。
猜你喜欢
  • 2014-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-15
  • 1970-01-01
  • 2014-11-04
  • 1970-01-01
相关资源
最近更新 更多