Child Action chỉ accessible bằng child request. Nó không respond đến URL requests. Nếu cố gắng truy cập qua URL, runtime error ném ra: "Child action is accessible only by a child request". Child action methods có thể invoke bằng child request từ view dùng Action() và RenderAction() HTML helpers.
Child action methods khác NonAction methods ở chỗ NonAction methods không thể invoke dùng Action() hoặc RenderAction() helpers.
Controller
Ví dụ
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);
}
}
}
Index View
@{
ViewBag.Title = "Countries List";
}
<h2>Countries List</h2>
@Html.Action("Countries", new { countries = new List<string>() { "USA", "UK", "India", "Australia" } })
Countries View (Partial)
@model List<string>
@foreach (string country in Model) {
<ul>
<li>
<b> @country </b>
</li>
</ul>
}
Output
Hiển thị danh sách countries được render từ child action.
Child actions cũng có thể invoke dùng "RenderAction()" HTML helper:
@{
Html.RenderAction("Countries", new { countryData = new List<string>() { "USA", "UK", "India", "Australia" } });
}
Action() vs RenderAction()
| Đặc điểm | @Html.Action() | @Html.RenderAction() |
|---|---|---|
| Return type | MvcHtmlString (chuỗi HTML) | void (ghi trực tiếp vào response stream) |
| Cú pháp | @Html.Action(...) | @{ Html.RenderAction(...); } |
| Performance | Tạo string trung gian | Tốt hơn (stream trực tiếp) |
| Sử dụng | Trong expression @Html.Action() | Trong code block @{ ... } |
Khi nào dùng ChildActionOnly
- Widget/Partial reusable components (menu, sidebar, footer)
- Cần pass data phức tạp từ parent view
- Logic rendering phức tạp tách biệt
- Reuse across multiple views
ASP.NET Core Equivalent: View Components
ASP.NET Core không có ChildActionOnly. Thay vào đó dùng View Components:
// ViewComponent
public class CountriesViewComponent : ViewComponent {
public IViewComponentResult Invoke(List countries) {
return View(countries);
}
}
// View (Default.cshtml)
@model List
@foreach (var country in Model) {
- @country
}
// Gọi từ parent view
@await Component.InvokeAsync("Countries", new { countries = new[] { "USA", "UK" } })
Lưu ý
- ChildActionOnly chỉ áp dụng cho ASP.NET MVC 5 trở xuống
- Không dùng cho API endpoints
- Child action có thể return PartialView, Content, Json, v.v.
- Tránh lạm dụng - có thể gây performance issue nếu lồng nhiều child actions