web-dev-qa-db-fra.com

Comment utiliser correctement Html.ActionLink avec ASP.NET MVC 4 Areas

J'ai récemment découvert les zones dans ASP.NET MVC 4 , que j'ai implémentées avec succès, mais je rencontre des problèmes avec l'assistant @Html.ActionLink dans mes vues Razor. L'URL générée par cette aide semble toujours être relative à l'URL de la page en cours.

Mon site Web est configuré dans IIS 7 (Win7) en tant que répertoire virtuel d’application à /Foo.

J'ai deux domaines enregistrés: Admin et Blogs. J'ai le code par défaut dans les fichiers AdminAreaRegistration.cs et BlogsAreaRegistration.cs. J'ai ajouté namespaces = new[] { "MvcProject.Controllers" } aux valeurs par défaut de RouteConfig par défaut:

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new {
                controller = "Home", action = "Index", id = UrlParameter.Optional,
                namespaces = new[] { "MvcProject.Controllers" }
            }
        );
    }
}

Lorsque je vais sur la page d'accueil de mon site: http://localhost/Foo, la page d'accueil de mon site est correctement chargée. À ce stade, tous les liens d'action ont leurs URL correctes.

Exemple de code de MvcProject/Views/Shared/_Layout.cshtml

<h2>Main Navigation</h2>
<ul>
    <li>@Html.ActionLink("Home", "Index", "Home")</li>
    <li>@Html.ActionLink("Blogs", "Index", "Blogs/Home")</li>
    <li>@Html.ActionLink("Admin", "Index", "Admin/Home")</li>
</ul>

Ceci rend correctement le code HTML comme suit:

<h2>Main Navigation</h2>
<ul>
    <li><a href="/Foo">Home</a></li>
    <li><a href="/Foo/Blogs/Home"></li>
    <li><a href="/Foo/Admin/Home"></li>
</ul>

Lorsque je navigue dans le navigateur vers "Blogs" par exemple, cette URL se charge correctement dans le navigateur: /Foo/Blogs/Home.

Maintenant, les liens de ma navigation principale changent d'URL:

<h2>Main Navigation</h2>
<ul>
    <li><a href="/Foo/Blogs/Home">Home</a></li>
    <li><a href="/Foo/Blogs/Blogs/Home"></li>
    <li><a href="/Foo/Blogs/Admin/Home"></li>
</ul>

Notez que "Blogs /" est ajouté au nom du répertoire virtuel IIS, de sorte que /Foo/Blogs/Home est maintenant /Foo/Blogs/Blogs/Home.

Les contrôleurs et les vues affichent un rendu correct, il suffit que les appels à @Html.ActionLink dans ma vue MvcProject/Views/Shared/_Layout.cshtml ne fonctionnent pas comme prévu.

J'ai l'impression de manquer quelque chose de trivial, mais aucune recherche n'a abouti à une réponse. Tous les articles de blog et tutoriels que j'ai trouvés pour l'implémentation de Areas dans ASP.NET MVC4 ne font aucune mention des modifications apportées au comportement de @Html.ActionLink.

38
Greg Burghardt

Je déteste répondre à ma propre question, mais @ Matt Bodily m'a mis sur la bonne voie.

La méthode @Html.Action appelle en fait un contrôleur et restitue la vue. Cela ne fonctionnerait donc pas pour créer un extrait de code HTML dans mon cas, car cela provoquait un appel de fonction récursif entraînant une exception StackOverflowException. @Url.Action(action, controller, { area = "abc" }) renvoie effectivement l'URL, mais j'ai finalement découvert une surcharge de Html.ActionLink qui a fourni une meilleure solution pour mon cas:

@Html.ActionLink("Admin", "Index", "Home", new { area = "Admin" }, null)

Remarque:, null est important dans ce cas, pour correspondre à la signature correcte.

Documentation: @ Html.ActionLink (LinkExtensions.ActionLink)

Documentation pour cette surcharge particulière:

LinkExtensions.ActionLink (Contrôleur, Action, Texte, RouteArgs, HtmlAttributes)

Il a été difficile de trouver de la documentation pour ces aides. J'ai tendance à chercher "Html.ActionLink" alors que j'aurais probablement dû chercher "LinkExtensions.ActionLink", si cela peut aider quelqu'un à l'avenir.

Marquant toujours la réponse de Matt comme réponse.

Edit: Trouvé encore un autre assistant HTML pour résoudre ceci:

@Html.RouteLink("Admin", new { action = "Index", controller = "Home", area = "Admin" })
68
Greg Burghardt

Comment je redirige vers une zone est l'ajouter en tant que paramètre

@Html.Action("Action", "Controller", new { area = "AreaName" })

pour la partie href d'un lien que j'utilise

@Url.Action("Action", "Controller", new { area = "AreaName" })
16
Matt Bodily

Juste pour ajouter mon bit:
N'oubliez pas qu'il vous faudra au moins deux zones dans votre application MVC pour que le routeValues: { area="" } fonctionne; sinon, la valeur de la zone sera utilisée comme paramètre de chaîne de requête et votre lien ressemblera à ceci: /?area= 

Si vous n'avez pas au moins 2 zones, vous pouvez résoudre ce problème en:
1. éditer la route par défaut dans RouteConfig.cs comme ceci:

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { area = "", controller = "Home", action = "Index", id = UrlParameter.Optional }
);

OR
2. Ajouter une zone fictive à votre projet MVC.

2
Achilles

Vous trouverez ci-dessous quelques exemples de moyens permettant de créer un bouton de lien dans MVC.

@Html.ActionLink("Admin", "Index", "Home", new { area = "Admin" }, null)  
@Html.RouteLink("Admin", new { action = "Index", controller = "Home", area = "Admin" })  
@Html.Action("Action", "Controller", new { area = "AreaName" })  
@Url.Action("Action", "Controller", new { area = "AreaName" })  
<a class="ui-btn" data-val="abc" href="/Home/Edit/ANTON">Edit</a>  
<a data-ajax="true" data-ajax-method="GET" data-ajax-mode="replace" data-ajax-update="#CustomerList" href="/Home/Germany">Customer from Germany</a>  
<a data-ajax="true" data-ajax-method="GET" data-ajax-mode="replace" data-ajax-update="#CustomerList" href="/Home/Mexico">Customer from Mexico</a> 

J'espère que ceci vous aidera.

0
Suraj Kumar