クエリー文字列の有無にかかわらず従来の要求をルーティングする

(開始前:こちら私はより簡潔な解決策を見つけたいと思っています。可能であれば、少し具体的な問題があります)

MVCで古いWebformsアプリケーションを書き直しています。いつものように、パーマリンクは壊れてはいけません。

私は標準の {controller}/{action}/{id} ルートを使用しています。レガシーパスは通常、 SomePage.aspx?ID = xxx であり、 Foo.aspx Bar (new URL: /バーまたは /バー/インデックス)と   Foo.aspx?ID = xxx Bar の詳細です(新しいURL:/Bar/View/xxx )。

可能な回避策の1つは、デフォルトの MapRoute の前に次の行を追加することです。

routes.MapRoute("Bar View", "Foo.aspx",
                new { controller = "Bar", action = "View" });

BarControllerで対応するアクションを定義する:

public ActionResult View(int? id)
{
    if (id == null)
        return RedirectToAction("Index");
    return View();
}

これには2つの問題があります。

  • ここでActionLinkを作成すると、従来の形式を使用します。
  • これをルートで処理したいと思います。 idをヌルにすることができ、コントローラのリダイレクトが間違っている

従来のURLを手作業でマッピングしても問題ありません(一般的なソリューションは必要ありません。約8ページしかありません)

これは新しいプロジェクトなので、私は何にも結びついていません。

6

2 答え

私は危険なアイデアこの回答をご覧ください。

私の新しい経路表は:

routes.MapRoute("Bar", "Bar/{action}/{id}",
                new
                {
                    controller = "Bar",
                    action = "Index",
                    id = UrlParameter.Optional
                });
routes.MapRoute("Bar View", "Foo.aspx",
                new {controller = "Bar", action = "View"},
                new {id = new QueryStringConstraint()});
routes.MapRoute("Bar Index", "Foo.aspx",
                new { controller = "Bar", action = "Index" });
routes.MapRoute("Default", /*...*/);

また、QueryStringConstraintを単純化することはできませんでした。

public class QueryStringConstraint : IRouteConstraint
{
    public bool Match(HttpContextBase httpContext, Route route,
                      string parameterName, RouteValueDictionary values,
                      RouteDirection routeDirection)
    {
        return httpContext.Request.QueryString.AllKeys
            .Contains(parameterName, StringComparer.InvariantCultureIgnoreCase);
    }
}
3
追加された
@DenisAgarevあなたの質問を理解できませんでした。
追加された 著者 Diego Mijelshon,
すべてが可能です。しかし、それは別の質問でしょう
追加された 著者 Diego Mijelshon,
ディーゴの素晴らしい答え、しかし、どのように "Bar/View?id = 3"ではなく "Bar/View/3"というURLを否定する方法はありますか?
追加された 著者 Denis Agarev,
申し訳ありませんが、私は間違いを犯しました))) "Bar/View/anything"のようなあなたのソリューションのURLは "Bar/View?id = 3"のようなクエリーストリングURLだけを許可する方法があります同じルートにも許可されています。
追加された 著者 Denis Agarev,

私はあなたが次のルートを指定すると信じています:

routes.MapRoute(
    null,
    "Bar/{action}/{id}",
     new { controller = "Bar", action = "View", id = UrlParameter.Optional },
     new { action = "Index|Next" } //contrain route from being used by other action (if required)
);

routes.MapRoute(
    null,
    "Foo.aspx/{id}",
    new { controller = "Bar", action = "View", id = UrlParameter.Optional }
);

//specify other routes here for the other legacy routes you have.

そうすれば、あなたの最初の問題を解決するはずです。ユーザーがURLにFoo.aspxを指定すると、Viewアクションに移動します。

アクションリンク:

@Html.ActionLink("Click me", "Index", "Bar")

が指定されている場合は、最初のルートが使用されます(オーダーが重要です)。

しかし、 Foo.aspx が指定されていれば、 Foo.aspx?id = ... を指定して別のルートに移動する方法を特定できませんでした。もう一つのルート。したがって、私はidがアクション内でnullかどうかをチェックします。しかし、これを見つけたら、私は非常に知りたいです。

お役に立てれば。

2
追加された
これは最初の問題(感謝!)を解決しますが、もう1つは難しいものです...
追加された 著者 Diego Mijelshon,