2009-11-04 8 views
6

私はMVC 2プレビュー2を使用しているWebアプリケーションを持っています。すべてのルートが登録された後、チェーンをさらに下にしてデコレータで各ルートをラップする必要があります。問題はルーティングを中断することです。何が起こるのかは、GetVirtualPathメソッドがアプリケーション内の他の領域(私は単一のプロジェクト領域を使用しています)と誤って一致します。デコレータが役に立つかどうかは関係ありません。次のパススルーを使用すると、それを解消するのに必要なのはすべてです。なぜルーティングデコレータはASP.NET MVC 2でルーティングを中断しますか?

すべてのルートが登録された後、単純なループでデコレータを割り当てます。

var routes = RouteTable.Routes; 
for (var i = 0; i < routes.Count; i++) 
{ 
    routes[i] = new RouteDecorator(routes[i]); 
} 

経路とエリアを壊さずにデコレータを安全に挿入するにはどうすればよいですか?

再現可能なソリューションはありますかto download hereです。再現では、ルートデコレータはコメントアウトされています。それを再びコメントするとルーティングが中断され、最初のダミーエリアのルーティングデータは、通常は対応するネームスペースのみと正しく一致するリンクと一致します。

答えて

5

エリア/ネームスペース情報を格納するためにDataTokens辞書を使用する方法があります。あなたがRouteBaseから継承しているので、おそらくIRouteWithAreaインターフェイスを実装する必要があります。これは、ルートにあるDataTokensがないためです。

ActionLinkのヘルパーは、間接的に、したがって、この新しいインターフェースの必要性をこれを呼び出すようだ:

public static string GetAreaName(RouteBase route) 
{ 
    IRouteWithArea area = route as IRouteWithArea; 
    if (area != null) 
    { 
     return area.Area; 
    } 
    Route route2 = route as Route; 
    if ((route2 != null) && (route2.DataTokens != null)) 
    { 
     return (route2.DataTokens["area"] as string); 
    } 
    return null; 
} 

[編集 - 2009年11月12日] 私は、次の問題が解決すると信じ、などデコレータは、複数回のルートを包む終わるようだ:デコレータに

追加プロパティ:

public RouteBase InnerRoute 
     { 
      get 
      { 
       return _route; 
      } 
     } 

インターフェイスの実装:

public string Area 
     { 
      get 
      { 

       RouteBase r = _route; 
       while (r is RouteDecorator) 
        r = ((RouteDecorator) r).InnerRoute; 
       string s = GetAreaToken(r); 
       if (s!= null) return s; 
       return null; 
      } 
     } 

     private string GetAreaToken(RouteBase r) 
     { 
      var route = r as Route; 
      if (route != null && route.DataTokens !=null && route.DataTokens.ContainsKey("area")) 
      { 
       return (route.DataTokens["area"] as string); 
      } 
      return null; 
     } 
    } 
+0

努力をいただきありがとうございます。 IRouteWithAreaを実装しても問題は解決しませんが、新しい方向へ私を連れていくかもしれません。ありがとうございました。 –

+0

デコレータは、ルートを複数回折り返してしまうように見えます。実際のソリューションを実装するためのコードを提供して私の答えを編集しましたが、なぜこれがむしろ奇妙なのかを知りたいのが理想です。 –

+0

これは間違いなくこの問題に対する答えです。私は産卵デコレータの問題をキャッチしませんでした。これは、何らかの奇妙な振る舞い、またはそれが起こる理由を理解していないと予想される振る舞いです。 –

0

RouteBaseではなくRouteクラスを飾るとどうなりますか?このような何かの

思う:

public class RouteDecorator: Route 
{ 
    readonly Route _route; 

    public RouteDecorator(Route route) 
    { 
     _route = route; 
    } 

    public override RouteData GetRouteData(HttpContextBase context) 
    { 
     return _route.GetRouteData(context); 
    } 

    public override VirtualPathData GetVirtualPath(RequestContext context, RouteValueDictionary values) 
    { 
     return _route.GetVirtualPath(context, values); 
    } 
} 

私もリフレクターとSystem.Web.Routing.dllをチェックアウトをお勧めします、それはあなたに何が起こっているかの洞察力を与える可能性があります。

そして、あなたがこれを行う場合にも、何が起こる、:

var routes = RouteTable.Routes.ToList(); 
RouteTable.Routes.Clear(); 
//or, alternatively, if the above doesn't work: 
//RouteTable.Routes = new RouteCollection(); 
foreach (var r in routes) 
{ 
    RouteTable.Routes.Add(new RouteDecorator(r)); 
} 

を私はそれが役立つと非常に期待しています。

+0

RouteCollectionはRouteBaseのコレクションなので、RouteBaseではなくRouteを使用することはできません。 ReflectorとMVC 2のソースコードを使用して、ここに投稿する前に問題を推測しています。あなたの他の提案(コレクションをクリアする?)は効果がありません。 –

関連する問題