ASP.Net MVC Html.ActionLinkが既存のルート値を使用しないようにする方法はありますか?

StackOverflow https://stackoverflow.com/questions/1817421

  •  08-07-2019
  •  | 
  •  

質問

作業しているWebサイトには、かなり複雑なルーティング構造があり、ルーティングエンジンを使用してURLを構築する必要がある 方法で作業する際にいくつかの問題が発生しています。

RegExベースのパターンマッチングを使用して、複数の変数を単一のルートセグメントにグループ化する検索結果ページがあります(つまり、" www.host.com/ {structuralParameters}"は次のようになります:" www.host。 com / variableA-variableB-variableC"-変数AからCはすべてオプションです)。これは、少しの作業の後にうまく機能しています。

私たちが経験している問題は、ActionLinkメソッドの迷惑な機能に関する問題を解決します。同じコントローラー/アクションをポイントすると、既存のルート値が必要かどうかにかかわらず保持されます。リンクの外観を制御することを好み、場合によっては、既存のパラメーターを保持することはできません。たとえば、サイトのメインナビゲーションが、パラメーターが設定されていない検索結果ページ(必要に応じてデフォルトの検索ページ)につながる場合です。これは、明らかな拡張ポイントなしで実装を指示しているように見えるASP.Net MVCフレームワークのまれなインスタンスであるため、迷惑な機能です-マスターページに簡単なナビゲーションリンクを記述するためのカスタムActionLinkコードを作成しないことをお勧めします!

このようなパラメーターを空の文字列に明示的に設定する必要があると言う人もいますが、これを試みると、パラメーターがルート値からクエリ文字列パラメーターに変更されるだけです。 ActionLinkメソッドにパラメーターとして明示的に渡していない値を明示的に除外する必要があるとは思えませんが、これが唯一のオプションである場合は使用します。ただし、現時点でクエリ文字列に表示されている場合は、パラメータをルートに直接入力するのと同じくらい役に立たない。

ルーティング構造がこの問題を悪化させることは承知しています-より単純なアプローチ(例:www.host.com/variableA/variableB/variableC)を使用した場合、おそらく問題はありませんが、URL構造は交渉できません-ユーザビリティ、SEO、およびリンク/コンテンツ共有に関する非常に具体的なニーズを満たすように設計されました。

Html.ActionLinkを使用して、現在のルートデータにフォールバックせずに(または可能であれば、ルートセグメントを明示的に除外する必要がある)リンクが同じアクションメソッドにつながる場合でも、ページへのリンクを生成するにはどうすればよいですか?

ルートセグメントを明示的に除外する必要がある場合、メソッドがルートをクエリ文字列パラメーターとしてレンダリングしないようにするにはどうすればよいですか

この一見小さな問題が、私たちに驚くほどの悲嘆を引き起こしているので、それを解決するための助けに感謝します。

編集:LukLedの要求に応じて、ActionLink呼び出しのサンプルを次に示します。

// I've made it generic, but this should call the Search action of the 
// ItemController, the text and title attribute should say "Link Text" but there
// should be no parameters - or maybe just the defaults, depending on the route.
// 
// Assume that this can be called from *any* page but should not be influenced by
// the current route - some routes will be called from other sections with the same
// structure/parameters.
Html.ActionLink( 
    "Link Text",
    "Search", 
    "Item", 
    new { }, 
    new { title = "Link Text" } 
);
役に立ちましたか?

解決

Html.ActionLink または Html.RouteLink (または任意のURL生成メソッド)を呼び出すときにルート値をnullまたは空の文字列に設定すると、" ambient"がクリアされます。ルート値。

たとえば、標準のMVCコントローラー/アクション/ IDルートで、「Home / Index / 123」にいるとします。 Html.RouteLink(new {id = 456})を呼び出すと、MVCは" ambient"を認識します。 controller =" Home" および action =" Index" のルート値。また、 id =" 123" のアンビエントルート値にも気づきますが、明示的な「456」で上書きされます。これにより、生成されたURLは" Home / Index / 456"になります。

パラメータの順序も重要です。たとえば、 Html.RouteLink(new {action =" About"})を呼び出したとします。 「概要」アクションは現在の「インデックス」を上書きします。アクション、および「ID」パラメータは完全にクリアされます!しかし、なぜ、あなたは尋ねますか?パラメータセグメントを無効にすると、その後のすべてのパラメータセグメントが無効になるためです。この場合、「アクション」は新しい明示的な値によって無効にされたため、その後に続く明示的な値を持たない「id」も無効になります。したがって、生成されるURLは「ホーム/概要」になります。 (IDなし)。

この同じシナリオで Html.RouteLink(new {action =""})を呼び出した場合、生成されるURLは" Home"になります。 「アクション」を無効にしたためです。空の文字列を使用すると、" id"無効化された「アクション」の後に来たため、同様に無効化されます。

他のヒント

問題の根本にある解決策

最適な解決策(回避策のような匂いはありません)は、ルートがありルーティングにある問題を解決するものであるようです。

RouteWithExclusions という名前のカスタム Route クラスを作成しました。これは、URLを生成するときに除外/削除する必要があるルート値の名前を定義できます。問題は、ルーティングがルートテーブルを経由し、後続のルートが同じルート値名を持たない場合です...

問題全体の詳細と説明は、にあります。私のブログ投稿とすべてのコードもそこに提供されています。このルーティングの問題を解決するのに役立つかもしれません。また、追加のパラメーターを受け取る2つの MapRoute 拡張メソッドを作成しました。

リンクを完全に制御したい場合は、自分でリンクを作成してください:

<a href="~/variableA/variableB/<%= Html.Encode(Model.Target) %>">Click Here</a>

href 属性内で必要なものに置き換えます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top