web-dev-qa-db-ja.com

asp.net mvcルーティング:デフォルトのアクションを使用するが、デフォルト以外のパラメーターを使用する方法は?

これまでの回答では、十分に定義していないことがわかったので、質問を書き直しています。参照用に元の質問を以下に残しておきます。

ルーティングを設定するときに、さまざまなURL /ルートパーツのデフォルトを指定できます。 VSウィザードが生成する例を考えてみましょう。

        routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "DefaultPage", action = "Index", id = UrlParameter.Optional } // Parameter defaults

この例では、コントローラーが指定されていない場合はDefaultPageControllerが使用され、アクションが指定されていない場合は「インデックス」アクションが使用されます。 URLは通常次のようになります:http://mysite/MyController/MyAction

次のようなアクションがURLにない場合:http://mysite/MyController次に、インデックスアクションが使用されます。

ここで、コントローラーのIndexとAnotherActionに2つのアクションがあると仮定します。それらに対応するURLはそれぞれhttp://mysite/MyControllerhttp://mysite/MyController/AnotherActionです。私の「インデックス」アクションはパラメータidを受け入れます。したがって、インデックスアクションにパラメータを渡す必要がある場合は、http://mysite/MyController/Index/123を実行できます。 URL http://mysite/MyControllerとは異なり、インデックスアクションを明示的に指定する必要があることに注意してください。私がやりたいのは、http://mysite/MyController/123の代わりにhttp://mysite/MyController/Index/123を渡すことができるようにすることです。このURLに「インデックス」は必要ありません。mvcエンジンに認識させたいのですが、http://mysite/MyController/123を要求すると、123はアクションではなく(この名前でアクションを定義していないため)、デフォルトのアクション「インデックス」へのパラメータ。これを実現するためにルーティングを設定するにはどうすればよいですか?

以下は、質問の元の文言です。


私はこのように定義された2つのメソッドを持つコントローラーを持っています

    public ActionResult Index()
    {
        return View();
    }

    [HttpPost]
    public ActionResult Index(SomeFormData data)
    {
        return View();

    }

これにより、ユーザーがこのURLに移動したとき(GET)と、その後フォームをポストバックしたとき(POST)の両方で、http://website/PageのようなURLを処理できます。

さて、ポストバックを処理するときに、ブラウザを次のURLにリダイレクトしたい場合があります。

http://website/Page/123

ここで、123は整数であり、コントローラーでこのURLを処理するメソッドが必要です。

これが機能するようにルーティングを設定するにはどうすればよいですか?現在、次のようなウィザードによって生成された「デフォルト」ルーティングがあります。

        routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "DefaultPage", action = "Index", id = UrlParameter.Optional } // Parameter defaults

次のような別のコントローラーメソッドを追加してみました。

public ActionResult Index(int id)
{
    return View();
}

ただし、あいまいなアクションの例外がスローされるため、これは機能しません。

コントローラータイプ「PageController」のアクション「Index」に対する現在の要求は、次のアクションメソッド間であいまいです。タイプPageControllerのSystem.Web.Mvc.ActionResult Index()タイプPageControllerのSystem.Web.Mvc.ActionResult Index(Int32)

このコントローラーには他のアクションもあることを付け加えなければなりません。 これ 私がしなかったらうまくいったでしょう。

17
Andrew Savinykh

これを解決する方法は次のとおりです。

ルート制約を作成して、URLに数字(123)のようなものがある場合、これはデフォルトのアクションのアクションパラメーターであり、そうでないものがある場合は、ルーティングエンジンに示すことができます。番号(AnotherAction)の場合、それはアクションです。

このコードを検討してください:

routes.MapRoute(
  "MyController", "MyController/{productId}", 
  new {controller="My", action="Index"}, 
  new {productId = @"\d+" });

このルート定義は、http://mysite/MyController/123のMyControllerの後の数値にのみ一致するため、同じコントローラーで別のアクションを呼び出すことを妨げることはありません。

ソース: ルート制約の作成

11
Andrew Savinykh

変数名をIDのままにしておくと、何も変更する必要はありません。

投稿の名前を「PostIndex」に変更し、次の属性を追加します。

[ActionName("Index")]

SO ここ についても同じ質問です。

わかりました、それが助けになるなら、ここにあなたのためのカット/ペーストの答えがあります。

public ActionResult Index()    {        
return View();    
}    
[AcceptVerbs(HttpVerbs.Post), ActionName("Index")]   
public ActionResult PostIndex(SomeFormData data)    {        
return View();    
}
3
NKCSS

ああ、私は今それを手に入れました。デフォルトルートでは不可能だと思います。カスタムルートをマッピングする必要があります。

    // /MyController/AnotherAction
    routes.MapRoute(
        null,
        "MyController/AnotherAction",
        new { controller = "DefaultPage", action = "AnotherAction" }
    );

    // /MyController
    // /MyController/id
    routes.MapRoute(
        null,
        "MyController/{id}",
        new { controller = "DefaultPage", action = "Index", id = UrlParameter.Optional }
    );

ps。デフォルトルート/ MyController/idなど最後にマップする必要があります。

2
cem

同じ見方を返したいと思いますが、2つの異なることをしていることを理解する必要があります。 1つは投稿の受信、もう1つはgetによるアクセス、もう1つはgetとパラメーターによるアクセスです...

異なる名前で3つのactionresultを実行し、View( "ThisIsTheResult")と同じビューを返す必要があります。

0
Alberto León