2016-05-31 4 views
0

.NET 4.6.1で動作するASP.NET MVC 5 Webアプリケーションがあります。UrlHelper.RouteUrl(routeName、RouteValueDictionary)がNULLを返します。

私は「フー」と呼ばれる自分のアプリケーション内の領域を持っているし、私の地域登録に私はそうのような名前のルートを追加:私はこのルートを使ってリンクを生成したい私のかみそりビューコードから

RegisterArea(AreaRegistrationContext context) { 

    context.MapRoute("Foo_Bar", "{tenantName}/foo/{fooId}/{fooRevision}", new { controller = "Foo", action = "Index" }); 

} 

を、だから私は:

RouteValueDictionary rd = new RouteValueDictionary(this.Url.RequestContext.RouteData.Values); 
rd["fooId"  ] = "123"; 
rd["fooRevision"] = "4"; 

this.Url.RouteUrl("Foo_Bar", rd); 

しかし、これはnullを返します。例外なし。その他の副作用はありません。 tenantNamecontrolleractionfooId、およびfooRevision

デバッガはrdは5名前付きの値が含まれていることを示しています。デバッグ中にareaも追加しましたが、それでもまだnullが返されます。

this.Url.RouteCollection["Foo_Bar"]がそのルートに対応するSystem.Web.Routing.Routeオブジェクトを返すので、ルートが存在することを確認しました。

.NETソースステッピングを試してみましたが、UrlHelperにステップ1まで進んだのに、GenerateUrl関数に入るとVisual Studio 2015 U2が常に失敗します。

答えて

0

私はステップ-にするために、.NET Frameworkのソースコード、このいずれかを把握しなければならなかった - 最初System.Web.Mvc.dllに、その後(今、.NET 4.5でSystem.Web.dllのスタブです)System.Web.Routing.dllに呼ばUrlHelper.RouteUrlに入るために。

答えは、だから、問題は、このラインにあったParsedRoute::Bindhttp://referencesource.microsoft.com/#System.Web/Routing/ParsedRoute.cs

にある:

RouteValueDictionary rd = new RouteValueDictionary(this.Url.RequestContext.RouteData.Values); 

これはrdは(継承)現在のリクエスト・コンテキストから値をコピーさせ、私は思いましたこれは望ましいことでした。Foo_Barはデフォルトのcontrolleractionのパラメータ値を提供しているため、rdにあったものより優先されますが、間違っていました。

UrlHelper.RouteUrlには、controlleractionの値が含まれていましたが、現在の要求であり、デフォルトとは異なります。

ParsedRoute::Bindの定義は、それが提供される場合RouteValueDictionaryはラインParsedRoute.cs 149を介して、133を参照(デフォルトに異なるパラメータ値を提供する。

をIフレームワークは、その場合に例外をスローする必要が感じる、アボートようなものですこの動作は文書化されていないようです。特に、すべての検索結果では、ルートが存在しないか、パラメータが不十分であるという問題が発生しています。私の場合、問題は方法で多くのパラメータが渡されました。

0

null値は、要求された値がどのルートとも一致しなかったことを示します。明示的にルート名を指定しているので、ルートFoo_Barが提供されたルート値入力と一致しないと言うことは安全です。

{tenantName}のデフォルト値は指定されていません(正常なデフォルト値がない場合は問題ありません)。{tenantName}は必須値です。 {tenantName}の値を指定すると、URLが正しく生成されます。

RouteValueDictionary rd1 = new RouteValueDictionary(); 
rd1["fooId"] = "123"; 
rd1["fooRevision"] = "4"; 

var url1 = this.Url.RouteUrl("Foo_Bar", rd1); 
// url1 value is null 

RouteValueDictionary rd2 = new RouteValueDictionary(); 
rd2["fooId"] = "123"; 
rd2["fooRevision"] = "4"; 
rd2["tenantName"] = "SomeTenant"; 

var url2 = this.Url.RouteUrl("Foo_Bar", rd2); 
// url2 value is /SomeTenant/foo/123/4 

注: MVC automatically reuses route values from the current request明示的に提供されていません。 this.Url.RequestContext.RouteData.Valuesをルートコレクションに明示的に追加する必要はありません。

もちろん、このコードを実行しているコンテキストには、既にtenantNameを明示的にルートコレクションに追加する必要はありません。

+0

辞書内の明示的な 'tenantName'は、それでもnullを返します。これは奇妙です。 – Dai

関連する問題