1

これを持っている

routes.MapRoute(
    "ShowPage",
    "default.aspx/{page}/{pagetype}",
    new {
        controller = "Info",
        action = "PageASPX",
        page = "emptypage",
        pagetype = "emptypagetype"
    }
);

キャッチdefault.aspx?page=order するには(古いサイトから新しいMVCサイトへの永続的なリダイレクトを生成する必要があります)

ルートデバッガーで確認できるようにルートは一致していますが、ルートに値がありません

Key          Value
page         emptypage 
pagetype     emptypagetype 
controller   Info 
action       PageASPX 

どうしたの??

4

1 に答える 1

1

MVCルート定義にはURLセグメントがあります。ルートは次のようになります。

default.aspx/{page}/{pagetype}

つまり、のようなリクエストは、URLセグメントとして提供されるため、ルート解決中に値default.aspx/orderを入力する必要があります。pageこれは、page後でモデルバインディングが発生し、コントローラーアクションが呼び出されたときにデータが入力されないという意味ではありません。

コントローラのアクションシグネチャが次のように見える場合:

public ActionResult PageASPX(string page, string pagetype)
{
    ...
}

これらの2つのパラメーターは、URLセグメントではなくクエリ変数として指定した場合でも、入力される可能性があります。唯一の要件は、ルーティングが欠落しているセグメント値のデフォルト値を提供しないことです(またはオプションとして設定されています)。デフォルトのMVCモデルバインダーは、pageアクションパラメーターに実際のクエリ変数値を入力します。

したがって、主なことは、ルーティング定義を変更する必要があるということです(私の答えの最後のセクションを参照してください)。

動作するはずのリクエスト

ルーティングが認識pageしてpagetypeURLセグメント変数を認識するためには、リクエストは次のようになります。

default.aspx/somepage
default.aspx/somepage/sometype

ルーティングでデフォルトが定義されていないpage場合、リクエストが次のようになったらpagetype、コントローラーアクションが取得さpageれ、パラメーターに正しい値が入力されます。pagetype

default.aspx/somepage
default.aspx/somepage/sometype
default.aspx?page=somepage
default.aspx?pagetype=sometype
default.aspx?page=somepage&pagetype=sometype

ルート値とクエリ文字列変数の混合

私のテストが示すように、Asp.net MVCは、値がある場合(URL自体にセグメントまたはルートのデフォルトとして提供される)、ルート値のオーバーライドを提供しません。あなたの場合、このURLをリクエストする場合:

default.aspx/routepage?page=querypage

アクションメソッドは、 routepagepageの値を持つパラメータを参照します。常に

これのより重要な側面は、ルート定義自体にデフォルト値を指定すると、URLから省略しても、クエリ文字列として設定できないことです。この問題を回避するには、次の2つの選択肢があります。

  1. set pageand pagetypeas UrlParameter.Optionalwhichを使用すると、URLに値がない場合に、クエリ文字列変数で値をオーバーライドできます。これは、URLセグメントが優先されるため、常にURLセグメントまたはクエリ文字列のみを使用でき、両方は使用できないことを意味します。

  2. URLセグメント変数とクエリ文字列変数の名前が異なります-欠点は、望ましくない二重パラメーターを使用してアクションを実行する必要があることです。

    public ActionResult PageASPX(string routePage, string routeType, string queryPage, string queryType)
    {
        string page = routePage ?? queryPage ?? string.Empty;
        string type = routeType ?? queryType ?? string.Emtpy;
        ...
    }
    

最良の解決策

ルーティングを変更して、URLセグメントとして提供される変数と、クエリ文字列変数として提供される変数に別々のルーティング定義を設定します。次に、すべての変数(セグメントとクエリ文字列内)が同じ名前を共有している限り、これらのルートを同じコントローラーアクションに配線します。

route.MapRoute(
    "InSegmentsBoth",
    "default.aspx/{page}/{pagetype}",
    new { controller = "Info", action = "PageASPX" }
);
route.MapRoute(
    "InSegmentsPage",
    "default.aspx/{page}",
    new { controller = Info"", action = "PageASPX" }
);
route.MapRoute(
    "InQueryString",
    "default.aspx",
    new { controller = "Info", action = "PageASPX" }
);

リクエストが次のように両方の値(セグメントとクエリ変数)を提供する場合

default.aspx/segmentpage?page=querypage

その場合、セグメント値が優先されるため、アクションパラメータはこのリクエストのsegmentpagepageの値になります。

于 2012-11-15T12:22:54.083 に答える