web-dev-qa-db-ja.com

ASP.NET MVC 4エリアでHtml.ActionLinkを正しく使用する方法

最近、 ASP.NET MVC 4のエリア を発見しました。これは正常に実装されましたが、Razorビューの@Html.ActionLinkヘルパーで問題が発生しています。このヘルパーが生成するURLは、常に現在のページのURLに関連しているようです。

IIS 7(Win7)で/Fooのアプリケーション仮想ディレクトリとしてWebサイトを構成しています。

管理者とブログの2つの領域が登録されています。 AdminAreaRegistration.csおよびBlogsAreaRegistration.csファイルにデフォルトコードがあります。デフォルトのRouteConfigのデフォルトにnamespaces = new[] { "MvcProject.Controllers" }を追加しました。

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

私のサイトのホームページに移動すると、http://localhost/Foo、サイトの「ホーム」ページが正しくロードされます。この時点で、すべてのアクションリンクには正しいURLがあります。

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>

これにより、HTMLが次のように正しくレンダリングされます。

<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>

たとえば、ブラウザで「ブログ」に移動すると、次のURLがブラウザに正しく読み込まれます:/Foo/Blogs/Home

これで、メインナビゲーションのリンクの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>

「Blogs /」がIIS仮想ディレクトリ名に追加されているため、/Foo/Blogs/Home/Foo/Blogs/Blogs/Homeになります。

コントローラーとビューは正常にレンダリングされます。@Html.ActionLinkビューのMvcProject/Views/Shared/_Layout.cshtmlへの呼び出しが期待どおりに機能しません。

私は些細なことを見逃しているように感じますが、答えを見つけ出すほどの検索はありません。 ASP.NET MVC4でAreasを実装するために見つけたすべてのブログ投稿とチュートリアルでは、@Html.ActionLinkの動作の変更について言及していません。

41
Greg Burghardt

私は自分の質問に答えるのは嫌いですが、@ Matt Bodilyは私を正しい軌道に乗せました。

@Html.Actionメソッドは実際にコントローラーを呼び出してビューをレンダリングします。この場合、HTMLのスニペットを作成しても機能しません。これにより、StackOverflowExceptionが発生する再帰的な関数呼び出しが発生したためです。 @Url.Action(action, controller, { area = "abc" })は実際にURLを返しますが、私のケースにより良いソリューションを提供するHtml.ActionLinkのオーバーロードをようやく発見しました。

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

注:, nullは、この場合、正しい署名と一致するために重要です。

ドキュメント: @ Html.ActionLink(LinkExtensions.ActionLink)

この特定のオーバーロードのドキュメント:

LinkExtensions.ActionLink(Controller、Action、Text、RouteArgs、HtmlAttributes)

これらのヘルパーのドキュメントを見つけるのは困難でした。 「LinkExtensions.ActionLink」を検索する必要があったときに、「Html.ActionLink」を検索する傾向があります。これが将来誰かに役立つ場合。

マットの回答をまだ答えとしてマークしています。

編集:これを解決するために、さらに別のHTMLヘルパーを見つけました。

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

エリアにリダイレクトする方法は、パラメーターとして追加することです

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

私が使用するリンクのhref部分について

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

私のビットを追加するだけです:
覚えておいて、routeValues: { area="" }を機能させるには、MVCアプリケーションに少なくとも2つの領域が必要です。そうでない場合、エリア値はクエリ文字列パラメータとして使用され、リンクは次のようになります。/?area=

少なくとも2つの領域がない場合は、次の方法でこの動作を修正できます。
1。 RouteConfig.csのデフォルトルートを次のように編集します。

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

OR
2。 MVCプロジェクトにダミー領域を追加します。

2
Achilles

以下は、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> 

これがお役に立てば幸いです。

0
Suraj Kumar