2011-03-25 3 views
44

J'ai ajouté un nouveau Area à mon projet MVC3 et j'essaye de lier de la page _Layout à la nouvelle Area. J'ai ajouté une zone appelée 'Admin' qui a un contrôleur 'Meets'.ASP.NET MVC `Html.ActionLink` entre" Areas "

J'ai utilisé le concepteur de studio visuel pour ajouter la zone afin qu'elle contienne la classe d'enregistrement de zone correcte, etc., et le fichier global.asax enregistre toutes les zones.

Cependant, quand on utilise les 2 liens d'action suivants dans une page à la racine, je rencontre quelques problèmes:

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

Lorsque vous cliquez sur les liens, je suis pris au Meets contrôleur dans Admin zone, où l'application continue à lancer une erreur indiquant qu'elle ne peut pas trouver la page d'index (même si la page d'index est présente dans le dossier Views du sous-répertoire Area.)

La commande href pour le 1er lien ressemble à ceci :

http://localhost/BCC/Meets?area=Admin

Et le href pour le 2ème lien ressemble à ceci:

http://localhost/BCC/Meets

Aussi, si je frappe le lien que je pense à créer:

http://localhost/BCC/Admin/Meets

Je reçois juste un ressource ne peut pas être trouvé erreur. Tout est très perplexe! J'espère que quelqu'un peut aider ...

+0

Qu'est-ce que "BCC" dans ce cas? Est-ce un répertoire virtuel? –

Répondre

7

Je compris cela - j'ai créé un nouveau projet de test et a fait exactement la même chose que je faisais avant et ça a marché ... puis après une inspection plus approfondie de toutes les choses liées à l'itinéraire entre les deux projets, j'ai trouvé une divergence.

Dans le fichier Global.asax dans mon application BCC, il y avait une ligne rogue de code qui avait inexplicablement apparu:

 public static void RegisterRoutes(RouteCollection routes) 
     { 
      // Problem here 
      routes.Clear(); 

      routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 

      routes.MapRoute(
       "Default", // Route name 
       "{controller}/{action}/{id}", // URL with parameters 
       new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults 
      ); 
     } 

     protected void Application_Start() 
     { 
      AreaRegistration.RegisterAllAreas(); 

      RegisterGlobalFilters(GlobalFilters.Filters); 
      RegisterRoutes(RouteTable.Routes); 
     } 

Comme vous pouvez le voir où mon commentaire est, à un moment ou un autre que j'avais placé l'appel de routes.Clear() au début de RegisterRoutes, ce qui signifiait après avoir enregistré les zones dans Application_Start, je vérifiais immédiatement ce que je venais d'enregistrer.

Merci pour l'aide ... elle a finalement conduit à mon salut!

68

Étrange en effet. Des mesures qui ont fonctionné parfaitement bien pour moi:

  1. Créer une nouvelle application ASP.NET MVC 3 en utilisant le modèle par défaut Visual Studio
  2. Ajouter une zone appelée Admin utilisant concepteur Visual Studio en cliquant droit sur le projet
  3. Ajouter un contrôleur dans ~/Areas/Admin/Controllers/MeetsController:

    public class MeetsController : Controller 
    { 
        public ActionResult Index() 
        { 
         return View(); 
        } 
    } 
    
  4. Ajouter une vue correspondante ~/Areas/Admin/Views/Meets/Index.cshtml

  5. Dans la mise en page (~/Views/Shared/_Layout.cshtml) ajouter des liens:

    @Html.ActionLink("Admin", "Index", "Meets", new { area = "Admin" }, null) 
    @Html.ActionLink("Admin", "Index", "Meets", new { area = "" }, null) 
    
  6. exécuter l'application.

Rendus HTML pour les points d'ancrage:

<a href="/Admin/Meets">Admin</a> 
<a href="/Meets">Admin</a> 

Comme prévu, les premiers travaux de liaison alors que le second ne fonctionne pas.

Alors, quelle est la différence avec votre configuration?

+0

Il n'y a pas de contrôleur "Admin" pour la zone "", dans votre cas, vous avez créé une nouvelle zone "Admin" avec un "MeetsController" et le premier lien devrait fonctionner comme prévu. Si vous voulez vraiment que le contrôleur de la zone "Admin" s'exécute 'n'importe où', vous pouvez essayer de déplacer toutes les vues, partiels, etc hors de la zone 'Admin' et dans la racine de votre application web. Je ne suis pas sûr à quel point cela fonctionnerait. –

3

Vérifiez que votre classe AdminAreaRegistration ressemble à ceci:

public class AdminAreaRegistration : AreaRegistration 
{ 
    public override string AreaName 
    { 
     get 
     { 
      return "Admin"; 
     } 
    } 

    public override void RegisterArea(AreaRegistrationContext context) 
    { 
     context.MapRoute(
      "Admin_default", 
      "Admin/{controller}/{action}/{id}", 
      new { action = "Index", id = UrlParameter.Optional } 
     ); 
    } 
} 

et que vous avez cela dans Global.asax.cs:

protected void Application_Start() 
{ 
    ... // ViewEngine Registration 
    AreaRegistration.RegisterAllAreas(); 
    ... // Other route registration 
} 
2

J'ai résolu ce problème en procédant comme suit.

Dans mes Global.asax.cs, je

public static void RegisterGlobalFilters(GlobalFilterCollection filters) 
    { 
     filters.Add(new HandleErrorAttribute()); 
    } 

    public static void RegisterRoutes(RouteCollection routes) 
    { 
     routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 
     routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.ico(/.*)?" }); 
    } 

    protected void Application_Start() 
    { 
     //Initialise IoC 
     IoC.Initialise(); 

     AreaRegistration.RegisterAllAreas(); 
     RegisterGlobalFilters(GlobalFilters.Filters); 
     RegisterRoutes(RouteTable.Routes); 
    } 

Dans mes PublicAreaRegistration.cs (espace public), j'ai

public class PublicAreaRegistration : AreaRegistration 
{ 
    public override string AreaName 
    { 
     get 
     { 
      return "Public"; 
     } 
    } 

    public override void RegisterArea(AreaRegistrationContext context) 
    { 
     context.MapRoute("Root", "", new { controller = "Home", action = "Index" }); 

     context.MapRoute(
      "Public_default", 
      "Public/{controller}/{action}/{id}", 
      new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
      , new[] { "<Project Namespace here>.Areas.Public.Controllers" } 
     ); 
    } 
} 

Dans mes AuthAreaRegistration.cs (région de accès restreint), j'ai

public class AuthAreaRegistration : AreaRegistration 
{ 
    public override string AreaName 
    { 
     get 
     { 
      return "Auth"; 
     } 
    } 

    public override void RegisterArea(AreaRegistrationContext context) 
    { 
     context.MapRoute(
      "Auth_default", 
      "Auth/{controller}/{action}/{id}", 
      new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
     ); 
    } 
} 

Et enfin, mes liens dans mes * pages .cshtml serait comme

1) @ Html.ActionLink ("Log Off", "LogOff", nouvelle {zone = "Public", controller = "Home"})

ou

2) @ Html.ActionLink ("Admin Area", "Index", nouveau {area = "Auth", controller = "Accueil"})

Espérons que cela fasse gagner des heures de recherche! BTW, je parle de MVC3 ici.

Kwex.

+0

Une note aux lecteurs, les exemples ActionLink ici se traduirait par le même problème que l'OP éprouvait, en dépit des autres changements, ils devraient être écrits comme suit: 1) @ Html.ActionLink ("Déconnexion", "LogOff" , new {area = "Public", controller = "Accueil"}, null) ou 2) @ Html.ActionLink ("Zone Admin", "Index", nouveau {area = "Auth", controller = " Accueil "}, null) –

28

Une autre option est d'utiliser RouteLink() au lieu de ActionLink(), qui court-circuite les enregistrements de zone au total:

Version ActionLink:

Html.ActionLink("Log Off", "LogOff", "Account", new { area = "" }, null) 

Version RouteLink:

Html.RouteLink("Log Off", "Default", 
    new { action = "LogOff", controller = "Account" }) 

Le le second paramètre est un «nom de route» qui est enregistré dans Global.asax.cs et dans diverses sous-classes «AreaRegistration». Pour utiliser 'RouteLink' pour lier entre différentes zones, il vous suffit de spécifier le nom de l'itinéraire correct.

Cet exemple suivant montre comment je générer trois liens vers différentes zones d'un bien partagé partiel, qui fonctionne quelle que soit la région, je suis « dans » (le cas échéant):

@Html.RouteLink("Blog", "Blog_default", 
    new { action = "Index", controller = "Article" }) 
<br/> 
@Html.RouteLink("Downloads", "Download_default", 
    new { action = "Index", controller = "Download" }) 
<br/> 
@Html.RouteLink("About", "Default", 
    new { action = "Index", controller = "About" }) 

Bonne programmation!

1

Cela peut ne pas être le cas pour la plupart des développeurs, mais j'ai rencontré ce problème lorsque j'ai ajouté un premier domaine et que je n'ai pas construit ma solution. Dès que j'ai construit ma solution les liens ont commencé à peupler correctement.

Questions connexes