Quand utiliseriez-vous l'attribut ChildActionOnly
? Qu'est-ce qu'un ChildAction
et dans quelles circonstances voudriez-vous restreindre une action à l'aide de cet attribut?
Quand utiliseriez-vous l'attribut ChildActionOnly
? Qu'est-ce qu'un ChildAction
et dans quelles circonstances voudriez-vous restreindre une action à l'aide de cet attribut?
Réponses:
L' ChildActionOnly
attribut garantit qu'une méthode d'action ne peut être appelée qu'en tant que méthode enfant à partir d'une vue. Une méthode d'action n'a pas besoin d'avoir cet attribut pour être utilisée comme action enfant, mais nous avons tendance à utiliser cet attribut pour empêcher les méthodes d'action d'être appelées à la suite d'une demande utilisateur. Après avoir défini une méthode d'action, nous devons créer ce qui sera rendu lorsque l'action est appelée. Les actions enfants sont généralement associées à des vues partielles, bien que ce ne soit pas obligatoire.
[ChildActionOnly] autorisant un accès restreint via un code dans View
Implémentation des informations d'état pour une URL de page spécifique. Exemple: la syntaxe de l'URL de la page de paiement (payant une seule fois) permet d'appeler des actions spécifiques de manière conditionnelle
// 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."
Ainsi, vous empêchez un GET vers un certain contrôleur directement, mais uniquement depuis un autre contrôleur / action. Probablement: vues partielles.
InvalidOperationException
quand une méthode marquée <ChildActionOnly>
est appelée via le navigateur?
Avec l' attribut [ChildActionOnly] annoté, une méthode d'action ne peut être appelée qu'en tant que méthode enfant à partir d'une vue. Voici un exemple pour [ChildActionOnly]. .
il existe deux méthodes d'action: Index () et MyDateTime () et les vues correspondantes: Index.cshtml et MyDateTime.cshtml. c'est 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);
}
}
Voici la vue pour 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>
Voici la vue partielle de MyDateTime.cshtml .
@model DateTime
<p>
This is the child action result: @Model.ToLongTimeString()
<br />
@ViewBag.Message
</p>
si vous exécutez l'application et faites cette demande http: // localhost: 57803 / home / mydatetime Le résultat sera une erreur de serveur comme ceci:
Cela signifie que vous ne pouvez pas appeler directement la vue partielle. mais il peut être appelé via la vue Index () comme dans Index.cshtml
@ Html.Action ("MyDateTime") // Appel de la vue partielle: MyDateTime ().
Si vous supprimez [ChildActionOnly] et faites la même requête http: // localhost: 57803 / home / mydatetime, cela vous permet d'obtenir le résultat de la vue partielle mydatetime:
This is the child action result. 12:53:31 PM
This is from MyDateTime()
NonAction
aussi, quelle différence cela fait-il?
Vous l'utiliseriez si vous l'utilisez RenderAction
dans l'une de vos vues, généralement pour rendre une vue partielle.
La raison de le marquer avec [ChildActionOnly]
est que vous avez besoin que la méthode du contrôleur soit publique afin que vous puissiez l'appeler avec, RenderAction
mais vous ne voulez pas que quelqu'un puisse naviguer vers une URL (par exemple / Controller / SomeChildAction) et voir les résultats de cela action directe.
RenderAction
ou l'autre
NonActionAttribute
dans de vrais projets?
private
ou protected
. Je ne peux pas vraiment penser à une bonne raison pour laquelle vous voudriez créer une méthode de contrôleur, public
sauf si vous vouliez pouvoir l'appeler directement ou viaRenderAction
Un peu tard à la fête, mais ...
Les autres réponses expliquent bien l'effet de l' [ChildActionOnly]
attribut. Cependant, dans la plupart des exemples, je n'arrêtais pas de me demander pourquoi je créerais une nouvelle méthode d'action juste pour rendre une vue partielle, dans une autre vue, alors que vous pouviez simplement effectuer @Html.Partial("_MyParialView")
un rendu directement dans la vue. Cela semblait être une couche inutile. Cependant, en enquêtant, j'ai trouvé qu'un avantage est que l'action enfant peut créer un modèle différent et le transmettre à la vue partielle. Le modèle nécessaire pour le partiel peut ne pas être disponible dans le modèle de la vue dans laquelle la vue partielle est rendue. Au lieu de modifier la structure du modèle pour y obtenir les objets / propriétés nécessaires juste pour rendre la vue partielle, vous pouvez appeler l'action enfant et demander à la méthode d'action de créer le modèle nécessaire pour la vue partielle.
Cela peut être utile, par exemple, dans _Layout.cshtml
. Si vous avez quelques propriétés communes à toutes les pages, une façon d'y parvenir est d'utiliser un modèle de vue de base et d'en hériter tous les autres modèles de vue. Ensuite, le _Layout
peut utiliser le modèle de vue de base et les propriétés communes. L'inconvénient (qui est subjectif) est que tous les modèles de vue doivent hériter du modèle de vue de base pour garantir que ces propriétés communes sont toujours disponibles. L'alternative est de rendre @Html.Action
dans ces lieux communs. La méthode d'action créerait un modèle distinct nécessaire pour la vue partielle commune à toutes les pages, ce qui n'aurait pas d'impact sur le modèle de la vue "principale". Dans cette alternative, la _Layout
page n'a pas besoin d'avoir un modèle. Il s'ensuit que tous les autres modèles de vue n'ont pas besoin d'hériter d'un modèle de vue de base.
Je suis sûr qu'il y a d'autres raisons d'utiliser l' [ChildActionOnly]
attribut, mais cela me semble être une bonne raison, alors j'ai pensé partager.
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