John Landheer
John Landheer

Reputation: 4019

Html.Action does not render actionmethods annotated with [HttpPost]

I have the follwing method on my controller:

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

and in my view I try:

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

But that gives an error: A public action method 'UnplannedCourses' was not found on controller 'Digidos.MVCUI.Controllers.StudentController'.

If I leave the [HttpPost] out, then it works, but I use the action later again from javascript so I would like to have only POST available.

Any ides?

Upvotes: 4

Views: 2669

Answers (2)

John Landheer
John Landheer

Reputation: 4019

I think my best bet is a new attribute based on the MVC sources:

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);
}

Upvotes: 4

tugberk
tugberk

Reputation: 58434

Html.Action is a html helper method and invokes your controller action with Http GET not POST.

Html.Action is a html helper method and invokes your controller action which accepts GET requests.

Edit:

If your intention is to protect that page from viewing through your browser, implement ChildActionOnly attribute as follows:

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

Edit:

If you would like to invoke your action through Http POST via JavaScript, have a look the at following post:

Working With JQuery Ajax API on ASP.NET MVC 3.0

Upvotes: 2

Related Questions