Использование ChildActionOnly в MVC
Когда бы вы использовали атрибут ChildActionOnly
? Что такое ChildAction
и при каких обстоятельствах вы хотели бы ограничить действие, используя этот атрибут?
6 ответов
ChildActionOnly
Атрибут гарантирует, что метод действия может быть вызван только как дочерний метод из представления. Метод действия не обязательно должен иметь этот атрибут для использования в качестве дочернего действия, но мы склонны использовать этот атрибут для предотвращения вызова методов действия в результате запроса пользователя. Определив метод действия, нам нужно создать то, что будет отображаться при вызове действия. Дочерние действия обычно связаны с частичными представлениями, хотя это не является обязательным.
[ChildActionOnly], разрешающий ограниченный доступ с помощью кода в представлении
Реализация информации о состоянии для определенного URL страницы. Пример: URL страницы оплаты (оплата только один раз) синтаксис бритвы позволяет назвать определенные действия условными
С аннотированным атрибутом [ChildActionOnly] метод действия может вызываться только как дочерний метод из представления. Вот пример для [ChildActionOnly].,
Есть два метода действия: Index() и MyDateTime() и соответствующие Views: Index.cshtml и MyDateTime.cshtml. это 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);
}
}
Вот представление для 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>
Вот MyDateTime.cshtml частичное представление.
@model DateTime
<p>
This is the child action result: @Model.ToLongTimeString()
<br />
@ViewBag.Message
</p>
если вы запустите приложение и выполните этот запрос http://localhost:57803/home/mydatetime Результатом будет ошибка сервера примерно так:
Это означает, что вы не можете напрямую вызвать частичное представление. но он может быть вызван через представление Index () как в Index.cshtml
@ Html.Action ("MyDateTime") // Вызов частичного представления: MyDateTime().
Если вы удалите [ChildActionOnly] и выполните тот же запрос http://localhost:57803/home/mydatetime, это позволит вам получить результат частичного просмотра mydatetime:
This is the child action result. 12:53:31 PM
This is from MyDateTime()
Вы бы использовали его, если вы используете RenderAction
в любом из ваших представлений, как правило, чтобы сделать частичное представление.
Причина пометки это [ChildActionOnly]
является то, что вам нужен метод контроллера, чтобы быть публичным, чтобы вы могли вызвать его с RenderAction
но вы не хотите, чтобы кто-либо имел возможность перейти к URL-адресу (например, /Controller/SomeChildAction) и просмотреть результаты этого действия напрямую.
К вашему сведению, [ChildActionOnly] недоступно в ASP.NET MVC Core. см. некоторую информацию здесь
Немного опоздал на вечеринку, но...
Другие ответы хорошо объясняют, какой эффект [ChildActionOnly]
Атрибут имеет. Тем не менее, в большинстве примеров я продолжал спрашивать себя, зачем создавать новый метод действия, просто чтобы визуализировать частичное представление в другом представлении, когда вы можете просто отобразить @Html.Partial("_MyParialView")
прямо в поле зрения. Это казалось ненужным слоем. Однако, как я выяснил, я обнаружил, что одним из преимуществ является то, что дочернее действие может создать другую модель и передать ее в частичное представление. Модель, необходимая для частичного представления, может быть недоступна в модели представления, в котором отображается частичное представление. Вместо того, чтобы изменять структуру модели для получения необходимых объектов / свойств там только для визуализации частичного представления, вы можете вызвать дочернее действие, а метод действия позаботится о создании модели, необходимой для частичного представления.
Это может пригодиться, например, в _Layout.cshtml
, Если у вас есть несколько свойств, общих для всех страниц, один из способов сделать это - использовать базовую модель представления и наследовать от нее все другие модели представления. Затем _Layout
Можно использовать модель базового вида и общие свойства. Недостатком (который является субъективным) является то, что все модели представлений должны наследоваться от модели базовых представлений, чтобы гарантировать, что эти общие свойства всегда доступны. Альтернатива состоит в том, чтобы сделать @Html.Action
в тех местах общего пользования. Метод действия создаст отдельную модель, необходимую для частичного представления, общего для всех страниц, что не повлияет на модель для "основного" представления. В этой альтернативе _Layout
страница не должна иметь модель. Отсюда следует, что все другие модели представлений не должны наследоваться от какой-либо базовой модели представлений.
Я уверен, что есть и другие причины, чтобы использовать [ChildActionOnly]
атрибут, но это кажется мне хорошим, поэтому я решил поделиться.
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.TempValue = "Index Action called at HomeController";
return View();
}
[ChildActionOnly]
public ActionResult ChildAction(string param)
{
ViewBag.Message = "Child Action called. " + param;
return View();
}
}
The code is initially invoking an Index action that in turn returns two Index views and at the View level it calls the ChildAction named “ChildAction”.
@{
ViewBag.Title = "Index";
}
<h2>
Index
</h2>
<!DOCTYPE html>
<html>
<head>
<title>Error</title>
</head>
<body>
<ul>
<li>
@ViewBag.TempValue
</li>
<li>@ViewBag.OnExceptionError</li>
@*<li>@{Html.RenderAction("ChildAction", new { param = "first" });}</li>@**@
@Html.Action("ChildAction", "Home", new { param = "first" })
</ul>
</body>
</html>
Copy and paste the code to see the result .thanks