ChildActionOnly 속성이란?
ASP.NET MVC에서 [ChildActionOnly] 속성이 적용된 액션 메서드는 오직 자식 요청(child request)을 통해서만 접근할 수 있습니다. 즉, 사용자가 브라우저 주소창에 해당 액션의 URL을 직접 입력해도 정상적인 응답을 받을 수 없으며, 대신 다음과 같은 런타임 오류가 발생합니다.
"자식 액션은 자식 요청을 통해서만 접근할 수 있습니다.(Child action is accessible only by a child request)"
자식 액션 메서드는 뷰(View) 내부에서 Action() 또는 RenderAction() HTML 헬퍼를 사용해 자식 요청을 생성함으로써 호출할 수 있습니다.
NonAction 메서드와의 차이점
자식 액션 메서드는 NonAction 메서드와 성격이 다릅니다. NonAction 메서드는 컨트롤러의 public 메서드를 액션으로 취급하지 않도록 만드는 속성으로, Action()이나 RenderAction() 헬퍼로도 호출할 수 없습니다. 반면 [ChildActionOnly]가 적용된 메서드는 이 두 헬퍼를 통해서는 호출이 가능하다는 점이 핵심 차이입니다.
URL로 직접 호출 시 발생하는 오류
아래 이미지는 자식 액션을 URL로 직접 호출하려고 할 때 나타나는 오류 화면입니다.

컨트롤러 예제
using System.Collections.Generic;
using System.Web.Mvc;
namespace DemoMvcApplication.Controllers{
public class HomeController : Controller{
public ActionResult Index(){
return View();
}
[ChildActionOnly]
public ActionResult Countries(List<string> countries){
return View(countries);
}
}
}위 코드에서 Countries 액션에는 [ChildActionOnly] 속성이 적용되어 있으므로 외부 URL 요청으로는 실행되지 않고, 반드시 뷰 내부에서만 호출될 수 있습니다.
Index 뷰
@{
ViewBag.Title = "Countries List";
}
<h2>Countries List</h2>
@Html.Action("Countries", new { countries = new List<string>() { "USA", "UK", "India", "Australia" } })@Html.Action() 헬퍼는 지정한 액션 메서드를 실행하고 그 결과를 문자열 형태로 부모 뷰에 삽입합니다. 여기서는 국가 목록 데이터를 전달하여 Countries 자식 액션을 호출하고 있습니다.
Countries 뷰
@model List<string>
@foreach (string country in Model){
<ul>
<li>
<b>
@country
</b>
</li>
</ul>
}실행 결과

국가 목록이 Index 페이지 안에 정상적으로 렌더링된 것을 확인할 수 있습니다.
RenderAction()을 사용한 호출 방법
자식 액션은 아래와 같이 RenderAction() HTML 헬퍼로도 호출할 수 있습니다.
@{
Html.RenderAction("Countries", new { countryData = new List<string>() {
"USA", "UK", "India", "Australia" } });
}두 헬퍼의 차이도 알아두면 유용합니다. Action()은 결과를 MvcHtmlString으로 반환하는 반면, RenderAction()은 결과를 응답 스트림(response stream)에 직접 기록하기 때문에 대용량 콘텐츠를 처리할 때 성능 면에서 약간 더 유리합니다.