2009-07-18 15 views
30

からのルート値を継承Url.RouteUrl(...)を防ぐために、どのようにしてあるマストヘッドで、は、現在のリクエスト

// ProductsController.cs 
public ActionMethod Index(string gender) { 

     // get all products for the gender 
} 

他の場所でショッピングカートに製品を表示するためのアクションメソッドを持っているとしましょう

<a href="<%= Url.RouteUrl("testimonials-route", new { }) %>" All Testimonials </a> 

このtestimonials-routeは、下記の最初のルートでglobal.ascxで定義されています:あなたは、サイト上の他のページへのHREFリンクを作成するために、Url.RouteUrlを使用しているすべてのページに表示されます。 上記のRouteUrlの呼び出しにはgenderが含まれていませんが、ルートはデフォルトの 'ニュートラル'で定義されているため、Testimonials.Index( "ニュートラル")が呼び出されると考えられます。

routes.MapRoute(
    "testimonials-route", 
    "testimonials/{gender}", 
    new { controller = "Testimonials", action = "Index", gender = "neutral" }, 
    new { gender = "(men|women|neutral)" } 
); 

routes.MapRoute(
    "products-route", 
    "products/{gender}", 
    new { controller = "Products", action = "Index", gender = (string)null }, 
    new { gender = "(men|women|neutral)" } 
); 

誰かがページ/products/womenを訪問した場合、我々は、誰かがページ/productsを訪れたならば、我々は(RouteUrlへの呼び出しはnullを返します)、空のHREFを取得/testimonials/women にHREFを取得します。

しかし、それは意味がありませんか? testimonials-routeは、ルート値を指定しないとデフォルトで'neutral'になっていますか?

何判明起こっていることUrl.RouteUrl(routeName, routeValues)ヘルパー拡張子が最初genderルート値のためにそのrouteValuesパラメータになりますということであり、それはその辞書でそれを見つけることができなかった場合、それは我々が(にしている現在のURLを見ていきますUrlは現在のリクエストのコンテキストを持つUrlHelperオブジェクトであることに注意してください)。

私たちがメンズ製品のページにいる場合、これは男性の栄誉へのリンクを与えるという意味では効果がありますが、RouteUrlコールの値を渡して明示的に明示しないと、 global.asax.csファイルでデフォルトとして 'neutral'を指定しました。

/products/を訪問した場合、私たちは'products-route'ルートをトリガーし、Products(null)メソッドが呼び出されました。 testimonials-routeを使用してURLを作成する場合、Url.RouteUrl()の呼び出しは実際にはgenderのこのnull値を継承します。 genderのデフォルトを'testimionials-route 'に指定しても、このヌル値は引き続き使用され、ルートは失敗し、RouteUrlはnullを返します。 [ノート:(男性|女性|ニュートラル)に制約があり、ヌルが適合しないためにルートに失敗しました]

実際には「コントローラ」と「アクション」が継承できます同じ方法。これにより、デフォルトコントローラを持つ明示的なルート名でRouteUrl(...)を呼び出す場合でも、URLが間違ったコントローラに完全に生成されることがあります。

この場合、いったんそれを理解すれば、非常に簡単にさまざまな方法で修正できますが、それ以外の場合には危険な動作を引き起こす可能性があります。これは設計上の可能性がありますが、間違いなく恐ろしいものです。

+0

元の質問の1年半後に賞金を追加する理由は、(a)フレームワークが今私のためにこれを行うかどうかを知りたいのですが、(b)なぜこれに2つのアップフォースしかないのか非常に不思議です。それは一般的な問題だと思ったので、私は何か間違っていると思っています! –

+0

{domain}タグには値がないのに、システムが自動的に提供するはずなので、これは私のブーティーを蹴っていました。一度これを変更すると、うまくいきました。 –

+0

RenderUrlを次のように呼び出してみましょう: '" ' - 何も上書きされません。 – Gerwald

答えて

26

私のソリューションは、このだった:私は今できる

public static string RouteUrl(this UrlHelper urlHelper, string routeName, object routeValues, bool inheritRouteParams) 
    { 
     if (inheritRouteParams) 
     { 
      // call standard method 
      return urlHelper.RouteUrl(routeName, routeValues); 
     } 
     else 
     { 
      // replace urlhelper with a new one that has no inherited route data 
      urlHelper = new UrlHelper(new RequestContext(urlHelper.RequestContext.HttpContext, new RouteData())); 
      return urlHelper.RouteUrl(routeName, routeValues); 
     } 
    } 

Url.RouteUrl('testimonials-route', new { }, false) 

、それは常に関係なく、同じように動作しません確かに知って

アンHtmlExtensionヘルパーメソッドどのようなコンテキスト。

実際の動作は、既存のUrlHelperを空白の「RouteData」で作成することです。つまり、継承するものはありません(null値でも)。

+0

私は自分の解決策に満足していますが、私はそれをグローバルに実施する方法があり、いつもこのオーバーロードを覚えておく必要はないと思います。うまくいけば、MVC4はこれをより詳細に制御するでしょう。 –

+0

私はまったく同じ問題に直面しました。これはとても役に立ちました!私は、リンクのために同じことをするためにHtmlHelper.RouteLinkメソッドを拡張することを考えていましたが、新しいHtmlHelperをインスタンス化するための構文を整理することに問題があります。 – goombaloon

+0

これは良い解決策です。私たちにとっては、これらのリンクはすべて同じ部分ビューになっていたので、新しいUrlHelperを変数としてインスタンス化し、その変数を標準のUrlプロパティではなく部分的に使用しました。 –

2

は、たぶん私はここに何かが欠けているが、なぜこのようにそれを設定していないよ:あなたのグローバルasaxで

、二つの経路作成します。次に

routes.MapRoute(
    "testimonial-mf", 
    "Testimonials/{gender}", 
    new { controller = "Testimonials", action = "Index" } 
); 

routes.MapRoute(
    "testimonial-neutral", 
    "Testimonials/Neutral", 
    new { controller = "Testimonials", action = "Index", gender="Neutral" } 
); 

を、代わりに、URLのUrl.Actionを使用します.RouteUrl:

私のマシン上で以下のURLに解決され、
<%= Url.Action("Testimonials", "Index") %> 
<%= Url.Action("Testimonials", "Index", new { gender = "Male" }) %> 
<%= Url.Action("Testimonials", "Index", new { gender = "Female" }) %> 

/Testimonials/Neutral 
/Testimonials/Male 
/Testimonials/Female 

これは受け入れ可能な解決策であるかどうかはわかりませんが、代替方法はありますか?

+0

残念ながら(または幸いにもおそらく!)、問題はURLの解析とルーティングにありません。これは期待通りに機能します。したがって、ここでの最初のルートで十分です(デフォルトパラメータを追加した場合)。既存のルート値が予期せず継承されると、実際にURLが作成されます。私が1年以上使ってきた解決策 - RouteUrlやRouteLinkの他のオーバーロードを使用する必要があるときに、ちょっと迷惑になり、メソッドオーバーロードを1トン作成する必要があります。答えがありがとう –

関連する問題