Using ChildActionOnly in MVC

When would you use the attribute ChildActionOnly? What is a ChildAction and in what circumstance would you want restrict an action using this attribute?


The ChildActionOnly attribute ensures that an action method can be called only as a child method from within a view. An action method doesn’t need to have this attribute to be used as a child action, but we tend to use this attribute to prevent the action methods from being invoked as a result of a user request. Having defined an action method, we need to create what will be rendered when the action is invoked. Child actions are typically associated with partial views, although this is not compulsory.

  1. [ChildActionOnly] allowing restricted access via code in View

  2. State Information implementation for specific page URL. Example: Payment Page URL (paying only once) razor syntax allows to call specific actions conditional


With [ChildActionOnly] attribute annotated, an action method can be called only as a child method from within a view. Here is an example for [ChildActionOnly]..

there are two action methods: Index() and MyDateTime() and corresponding Views: Index.cshtml and MyDateTime.cshtml. this is HomeController.cs

public class HomeController : Controller
 {
    public ActionResult Index()
    {
        ViewBag.Message = "This is from Index()";
        var model = DateTime.Now;
        return View(model);
    }

    [ChildActionOnly]
    public PartialViewResult MyDateTime()
    {
        ViewBag.Message = "This is from MyDateTime()";

        var model = DateTime.Now;
        return PartialView(model);
    } 
}

Here is the view for Index.cshtml.

@model DateTime
@{
    ViewBag.Title = "Index";
}
<h2>
    Index</h2>
<div>
    This is the index view for Home : @Model.ToLongTimeString()
</div>
<div>
    @Html.Action("MyDateTime")  // Calling the partial view: MyDateTime().
</div>

<div>
    @ViewBag.Message
</div>

Here is MyDateTime.cshtml partial view.

@model DateTime

<p>
This is the child action result: @Model.ToLongTimeString()
<br />
@ViewBag.Message
</p>
 if you run the application and do this request http://localhost:57803/home/mydatetime
 The result will be Server Error like so: 

enter image description here

This means you can not directly call the partial view. but it can be called via Index() view as in the Index.cshtml

     @Html.Action("MyDateTime")  // Calling the partial view: MyDateTime().
 
If you remove [ChildActionOnly] and do the same request http://localhost:57803/home/mydatetime it allows you to get the mydatetime partial view result:
This is the child action result. 12:53:31 PM 
This is from MyDateTime()

You would use it if you are using RenderAction in any of your views, usually to render a partial view.

The reason for marking it with [ChildActionOnly] is that you need the controller method to be public so you can call it with RenderAction but you don't want someone to be able to navigate to a URL (e.g. /Controller/SomeChildAction) and see the results of that action directly.