web-dev-qa-db-ja.com

「エリア」間のASP.NET MVC `Html.ActionLink`

MVC3プロジェクトに新しいエリアを追加しました。_Layoutページから新しいエリアにリンクしようとしています。コントローラ「Meets」を持つ「Admin」というエリアを追加しました。

Visual Studioデザイナーを使用してエリアを追加し、エリア登録クラスなどが正しくなるようにしました。また、global.asaxファイルはすべてのエリアを登録しています。

ただし、ルートのページで次の2つのアクションリンクを使用すると、いくつかの問題が発生します。

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

両方のリンクをクリックすると、管理領域のMeetsコントローラーに移動します。アプリケーションは、インデックスページが見つからないことを示すエラーをスローします(エリアサブのビューフォルダーにインデックスページがある場合でも)。ディレクトリ。

最初のリンクのhrefは次のようになります。

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

2番目のリンクのhrefは次のようになります。

http://localhost/BCC/Meets

また、作成する予定のリンクにヒットした場合:

http://localhost/BCC/Admin/Meets

リソースが見つからないというエラーが表示されるだけです。非常に困惑しています!誰かが助けてくれることを願っています...

48
jcvandan

私はこれを理解しました-私は新しいテストプロジェクトを作成し、以前とまったく同じことを行い、それが機能しました...その後、2つのプロジェクト間のルート関連のすべてのものをさらに検査した後、矛盾が見つかりました。

私のBCCアプリケーションのglobal.asaxファイルには、不可解に表示された不正なコード行がありました。

        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);
        }

私のコメントがどこにあるかを見ることができるように、RegisterRoutesの最初にroutes.Clear()呼び出しを配置し​​ていました。つまり、Application_Startにエリアを登録した後、すぐにクリアしていました登録済み。

助けてくれてありがとう...最終的には私の救いにつながりました!

7
jcvandan

本当に奇妙です。私にとって完全にうまくいった手順:

  1. デフォルトのVisual Studioテンプレートを使用して、新しいASP.NET MVC 3アプリケーションを作成します。
  2. プロジェクトを右クリックして、Visual Studioデザイナーを使用してAdminというエリアを追加します
  3. ~/Areas/Admin/Controllers/MeetsControllerに新しいコントローラーを追加します。

    public class MeetsController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }
    }
    
  4. 対応するビューを追加~/Areas/Admin/Views/Meets/Index.cshtml

  5. レイアウト(~/Views/Shared/_Layout.cshtml)にリンクを追加します:

    @Html.ActionLink("Admin", "Index", "Meets", new { area = "Admin" }, null)
    @Html.ActionLink("Admin", "Index", "Meets", new { area = "" }, null)
    
  6. アプリケーションを実行します。

アンカー用にレンダリングされたHTML:

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

予想どおり、最初のリンクは機能しますが、2番目のリンクは機能しません。

それでは、セットアップとの違いは何ですか?

73
Darin Dimitrov

別のオプションは、ActionLink()の代わりにRouteLink()を使用することです。これにより、エリア登録を完全にバイパスできます。

ActionLinkバージョン:

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

RouteLinkバージョン:

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

2番目のパラメーターは、Global.asax.csおよびさまざまな「AreaRegistration」サブクラスに登録されている「ルート名」です。 「RouteLink」を使用して異なるエリア間をリンクするには、正しいルート名を指定するだけです。

次の例は、共有パーシャルから異なるエリアへの3つのリンクを生成する方法を示しています。これは、「いる」エリア(ある場合)に関係なく正しく機能します。

@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" })

ハッピーコーディング!

30
Shaun Wilson

AdminAreaRegistrationクラスが次のようになっていることを確認します。

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 }
        );
    }
}

そして、あなたはこれをGlobal.asax.cs

protected void Application_Start()
{
    ... // ViewEngine Registration
    AreaRegistration.RegisterAllAreas();
    ... // Other route registration
}
3
Mikael Östberg

私は次のことを行ってこの問題を解決しました。

Global.asax.csには、

    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);
    }

PublicAreaRegistration.cs(パブリックエリア)には、

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" }
        );
    }
}

AuthAreaRegistration.cs(制限付きアクセスのエリア)に、

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 }
        );
    }
}

最後に、*。cshtmlページのリンクは次のようになります

1)@ Html.ActionLink( "Log Off"、 "LogOff"、new {area = "Public"、controller = "Home"})

または

2)@ Html.ActionLink( "Admin Area"、 "Index"、new {area = "Auth"、controller = "Home"})

これが誰かの研究時間を節約することを願っています!ところで、私はMVC3についてここで話している。

クウェックス。

2
Kwex

これはほとんどの開発者には当てはまらないかもしれませんが、最初の領域を追加してソリューションを構築しなかったときにこの問題に遭遇しました。ソリューションを構築するとすぐに、リンクが正しく挿入され始めました。

1
Abhi