web-dev-qa-db-fra.com

Comment retourner une vue partielle d'un autre contrôleur par contrôleur?

J'ai un fichier XXX.cshtml dans un dossier Views\ABC. Son contrôleur est ABC

J'ai aussi une méthode d'action dans mon contrôleur DEF qui renvoie un Partialview("XXX" , xyzmodel)

Je reçois une erreur "vue non trouvée".

Comment appeler ça view depuis un autre contrôleur

71
Vinit Patel

Normalement, les vues appartiennent à un contrôleur spécifique correspondant qui prend en charge la configuration requise, ou la vue appartient au dossier Views/Shared si elle est partagée entre plusieurs contrôleurs ( d'où le nom).

"Réponse" (mais non recommandé - voir ci-dessous):

Vous pouvez vous référer à des vues/vues partielles d’un autre contrôleur, en spécifiant le chemin complet (y compris l’extension) comme:

return PartialView("~/views/ABC/XXX.cshtml", zyxmodel);

ou un chemin relatif (sans extension), basé sur la réponse de @Max Toro

return PartialView("../ABC/XXX", zyxmodel);

MAIS CEC IS PAS UN BIEN IDEA TOUJOURS

* Remarque: Ce sont les deux seules syntaxes qui fonctionnent . not ABC\\XXX ou ABC/XXX ou toute autre variante, car ces chemins sont tous relatifs et ne trouvent pas de correspondance.

Meilleures alternatives:

Vous pouvez également utiliser Html.Renderpartial dans votre vue, mais cela nécessite également l'extension:

Html.RenderPartial("~/Views/ControllerName/ViewName.cshtml", modeldata);

Utilisez @Html.Partial pour la syntaxe Razor en ligne:

@Html.Partial("~/Views/ControllerName/ViewName.cshtml", modeldata)

Vous pouvez utiliser la syntaxe ../controller/view sans extension (à nouveau crédit à @Max Toro):

@Html.Partial("../ControllerName/ViewName", modeldata)

Remarque: Apparemment, RenderPartial est légèrement plus rapide que Partiel, mais ce n'est pas important.

Si vous voulez réellement appeler l’autre contrôleur, utilisez:

@Html.Action("action", "controller", parameters)

Solution recommandée: @ Html.Action

Ma préférence personnelle est d'utiliser @Html.Action car cela permet à chaque contrôleur de gérer ses propres vues, plutôt que les vues de références croisées d'autres contrôleurs (ce qui conduit à un grand désordre ressemblant à des spaghettis).

Vous devez normalement transmettre uniquement les valeurs de clé requises (comme toute autre vue), par exemple. pour votre exemple:

@Html.Action("XXX", "ABC", new {id = model.xyzId })

Ceci exécutera l'action ABC.XXX et rendra le résultat sur place. Cela permet aux vues et aux contrôleurs de rester séparément autonomes (c'est-à-dire réutilisables).

Mise à jour septembre 2014:

Je viens de frapper une situation où je ne pouvais pas utiliser @ Html.Action, mais que je devais créer un chemin de vue basé sur un nom action et controller. À cette fin, j'ai ajouté cette simple méthode d'extension View à UrlHelper afin que vous puissiez dire return PartialView(Url.View("actionName", "controllerName"), modelData):

public static class UrlHelperExtension
{
    /// <summary>
    /// Return a view path based on an action name and controller name
    /// </summary>
    /// <param name="url">Context for extension method</param>
    /// <param name="action">Action name</param>
    /// <param name="controller">Controller name</param>
    /// <returns>A string in the form "~/views/{controller}/{action}.cshtml</returns>
    public static string View(this UrlHelper url, string action, string controller)
    {
        return string.Format("~/Views/{1}/{0}.cshtml", action, controller);
    }
}
147
Gone Coding

Le contrôle recherche une vue dans l'ordre suivant:

  • D'abord dans le dossier partagé
  • Puis dans le dossier correspondant au contrôleur actuel (dans votre cas, c'est Vues/DEF)

Comme vous n'avez pas xxx.cshtml à ces emplacements, une erreur "view not found" est renvoyée.

Solution: Vous pouvez utiliser le chemin complet de votre vue:

Comme

 PartialView("~/views/ABC/XXX.cshtml", zyxmodel);
10
Arun Chandran C

Vous pouvez simplement utiliser:

PartialView("../ABC/XXX")
6
Max Toro