Kiedy użyjesz atrybutu ChildActionOnly
? Co to jest ChildAction
i w jakich okolicznościach chcesz ograniczyć działanie za pomocą tego atrybutu?
Kiedy użyjesz atrybutu ChildActionOnly
? Co to jest ChildAction
i w jakich okolicznościach chcesz ograniczyć działanie za pomocą tego atrybutu?
Odpowiedzi:
ChildActionOnly
Atrybut zapewnia, że metoda działania można nazwać tylko jako sposób dziecko od wewnątrz widoku. Metoda akcji nie musi mieć tego atrybutu, aby była używana jako akcja podrzędna, ale zwykle używamy tego atrybutu, aby zapobiec wywoływaniu metod akcji w wyniku żądania użytkownika. Po zdefiniowaniu metody akcji musimy stworzyć to, co będzie renderowane, gdy akcja zostanie wywołana. Działania dzieci są zwykle związane z częściowymi poglądami, chociaż nie jest to obowiązkowe.
[ChildActionOnly] zezwalające na ograniczony dostęp za pomocą kodu w widoku
Implementacja informacji o stanie dla określonego adresu URL strony. Przykład: URL strony płatności (płacąc tylko raz) składnia maszynki do golenia umożliwia wywołanie określonych akcji jako warunkowe
// example from Music Store // GET: /ShoppingCart/CartSummary [ChildActionOnly] public ActionResult CartSummary() { // your stuff } /ShoppingCart/CartSummary will return "The action 'CartSummary' is accessible only by a child request."
Więc uniemożliwiasz GET bezpośrednio do określonego kontrolera, ale tylko z innego kontrolera / akcji. Prawdopodobnie: _ Częściowe wyświetlenia.
InvalidOperationException
kiedy zaznaczona metoda <ChildActionOnly>
jest wywoływana przez przeglądarkę?
W przypadku atrybutu [ChildActionOnly] z adnotacją metodę akcji można wywołać tylko jako metodę podrzędną z poziomu widoku. Oto przykład dla [ChildActionOnly]. .
istnieją dwie metody akcji: Index () i MyDateTime () oraz odpowiadające im widoki: Index.cshtml i MyDateTime.cshtml. to jest 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);
}
}
Oto widok pliku 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>
Oto częściowy widok MyDateTime.cshtml .
@model DateTime
<p>
This is the child action result: @Model.ToLongTimeString()
<br />
@ViewBag.Message
</p>
jeśli uruchomisz aplikację i wykonasz to żądanie http: // localhost: 57803 / home / mydatetime Rezultatem będzie błąd serwera w następujący sposób:
Oznacza to, że nie możesz bezpośrednio wywołać częściowego widoku. ale można go wywołać za pomocą widoku Index (), tak jak w pliku Index.cshtml
@ Html.Action ("MyDateTime") // Wywołanie częściowego widoku: MyDateTime ().
Jeśli usuniesz [ChildActionOnly] i wykonasz to samo żądanie http: // localhost: 57803 / home / mydatetime, pozwoli to uzyskać wynik częściowego widoku mydatetime:
This is the child action result. 12:53:31 PM
This is from MyDateTime()
NonAction
również, co to za różnica?
Użyjesz go, jeśli używasz RenderAction
w którymkolwiek ze swoich widoków, zwykle do renderowania widoku częściowego.
Powodem oznaczenia tego [ChildActionOnly]
jest to, że potrzebujesz metody kontrolera, aby była publiczna, więc możesz ją wywołać, RenderAction
ale nie chcesz, aby ktoś mógł przejść do adresu URL (np. / Controller / SomeChildAction) i zobaczyć wyniki tego działanie bezpośrednio.
RenderAction
żadnego
NonActionAttribute
rzeczywistych projektów?
private
lub protected
. Naprawdę nie mogę wymyślić żadnego dobrego powodu, dla którego chciałbyś stworzyć metodę kontrolera, public
chyba że chciałbyś mieć możliwość wywołania jej bezpośrednio lub przezRenderAction
Trochę za późno na imprezę, ale ...
Pozostałe odpowiedzi dobrze wyjaśniają, jaki wpływ [ChildActionOnly]
ma ten atrybut. Jednak w większości przykładów ciągle zadawałem sobie pytanie, dlaczego tworzyłem nową metodę akcji tylko po to, aby renderować częściowy widok w innym widoku, skoro można po prostu renderować @Html.Partial("_MyParialView")
bezpośrednio w widoku. Wydawało się, że jest to niepotrzebna warstwa. Jednak, gdy badałem, odkryłem, że jedną z korzyści jest to, że działanie dziecka może stworzyć inny model i przekazać go częściowemu poglądowi. Model potrzebny dla częściowej może nie być dostępny w modelu widoku, w którym renderowany jest widok częściowy. Zamiast modyfikować strukturę modelu, aby uzyskać potrzebne obiekty / właściwości tylko do renderowania częściowego widoku, możesz wywołać akcję potomną i zlecić metodzie akcji utworzenie modelu potrzebnego do widoku częściowego.
Może się to przydać na przykład w _Layout.cshtml
. Jeśli masz kilka właściwości wspólnych dla wszystkich stron, jednym ze sposobów osiągnięcia tego jest użycie modelu widoku bazowego i dziedziczenie z niego wszystkich innych modeli widoku. Następnie _Layout
może użyć modelu widoku bazowego i wspólnych właściwości. Wadą (która jest subiektywna) jest to, że wszystkie modele widoków muszą dziedziczyć z modelu widoku podstawowego, aby zagwarantować, że te wspólne właściwości są zawsze dostępne. Alternatywą jest renderowanie @Html.Action
w tych wspólnych miejscach. Metoda akcji stworzyłaby oddzielny model potrzebny dla częściowego widoku wspólnego dla wszystkich stron, co nie wpłynęłoby na model dla „głównego” widoku. W tym przypadku _Layout
strona nie musi mieć modelu. Wynika z tego, że wszystkie inne modele widoku nie muszą dziedziczyć z żadnego modelu widoku bazowego.
Jestem pewien, że istnieją inne powody, dla których warto używać tego [ChildActionOnly]
atrybutu, ale wydaje mi się, że jest to dobry, więc pomyślałem, że się nim podzielę.
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