web-dev-qa-db-fra.com

Utilisation de ChildActionOnly dans MVC

Quand utiliseriez-vous l'attribut ChildActionOnly? Qu'est-ce qu'un ChildAction et dans quelle circonstance voudriez-vous restreindre une action à l'aide de cet attribut?

160
Rafael Herik

L'attribut ChildActionOnly 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 de cet attribut pour être utilisée en tant qu’action enfant, mais nous avons tendance à l’utiliser pour empêcher que les méthodes d’action ne soient appelées à la suite d’une demande de l’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 cela ne soit pas obligatoire.

  1. [ChildActionOnly] autorisant un accès restreint via le code dans la vue

  2. Implémentation des informations d'état pour une URL de page spécifique. Exemple: URL de la page de paiement (ne payant qu’une seule fois) La syntaxe de rasoir permet d’appeler des actions spécifiques conditionnelles.

157
Tomasz Jaskuλa

Avec [ChildActionOnly] attribut annoté, une méthode d'action ne peut être appelée que comme 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 MyDateTime.cshtml vue partielle.

@model DateTime

<p>
This is the child action result: @Model.ToLongTimeString()
<br />
@ViewBag.Message
</p>
 si vous exécutez l'application et faites cette requête http: // localhost: 57803/home/mydatetime 
 Le résultat sera Erreur du serveur comme ceci: 

enter image description here

Cela signifie que vous ne pouvez pas appeler directement la vue partielle. mais il peut être appelé via Index () comme dans Index.cshtml

 @ Html.Action ("MyDateTime") // Appel de la vue partielle: MyDateTime (). 
 
Si vous supprimez [ChildActionOnly] et effectuez la même requête http: // localhost: 57803/home/mydatetime, il 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()
118
yantaq

Vous l'utiliseriez si vous utilisiez RenderAction dans l'une de vos vues, généralement pour restituer 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 de pouvoir l'appeler avec RenderAction mais vous ne voulez pas que quelqu'un puisse accéder à une URL (par exemple/Controller/SomeChildAction) et voyez directement les résultats de cette action.

72
Eric Petroelje

Pour votre information, [ChildActionOnly] n'est pas disponible dans ASP.NET MVC Core. voir des infos ici

9
Joseph Wu

Un peu tard pour la fête, mais ...

Les autres réponses expliquent bien l’effet de l’attribut [ChildActionOnly]. Cependant, dans la plupart des exemples, je me suis toujours demandé pourquoi je créerais une nouvelle méthode d'action uniquement pour rendre une vue partielle, dans une autre vue, alors que vous pouviez simplement rendre @Html.Partial("_MyParialView") directement dans la vue. Cela semblait être une couche inutile. Cependant, au cours de mon enquête, j’ai trouvé que l’un des avantages était que l’action enfant pouvait créer un modèle différent et le transmettre à la vue partielle. Le modèle requis 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 obtenir les objets/propriétés nécessaires uniquement pour restituer la vue partielle, vous pouvez appeler l'action enfant et demander à la méthode d'action de créer le modèle nécessaire à la vue partielle.

Cela peut être pratique, par exemple dans _Layout.cshtml. Si vous avez quelques propriétés communes à toutes les pages, vous pouvez utiliser un modèle de vue de base et en hériter tous les autres. Ensuite, le _Layout peut utiliser le modèle de vue de base et les propriétés communes. L'inconvénient (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 consiste à rendre @Html.Action dans ces lieux communs. La méthode d'action créerait un modèle séparé nécessaire pour la vue partielle commune à toutes les pages, ce qui n'aurait aucune incidence sur le modèle de la vue "principale". Dans cette alternative, la page _Layout n'a pas besoin de modèle. Il s'ensuit que tous les autres modèles de vue ne doivent pas hériter d'un modèle de vue de base.

Je suis sûr qu'il existe d'autres raisons d'utiliser l'attribut [ChildActionOnly], mais cela me semble bon, alors j'ai pensé partager.

6
neizan
    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 
0
Hamid Nawaz