ルーティング:現在のアクション要求[…]は、次のアクションメソッド間であいまいです


100

と呼ばれるビューBrowse.chtmlがあり、ユーザーは検索用語を入力するか、検索用語を空白のままにすることができます。検索語句を入力するときにページを表示しhttp://localhost:62019/Gallery/Browse/{Searchterm} 、何も入力しない場合にブラウザをに表示したいhttp://localhost:62019/Gallery/Browse/Start/Here

これを試すと、エラーが発生します。

コントローラータイプ 'GalleryController'に対するアクション 'Browse'の現在の要求は、次のアクションメソッド間で不明確です:タイプAutoApp_MVC.Controllers.GalleryControllerに対するSystem.Web.Mvc.ActionResult Browse(System.String)System.Web.Mvc.ActionResult Browse (Int32、System.String)タイプAutoApp_MVC.Controllers.GalleryController

私がMVCで行っていることはすべて初めてです。この時点で他に何を試すかわかりません。

public ActionResult Browse(string id)
{
    var summaries = /* search using id as search term */
    return View(summaries);
}

public ActionResult Browse(string name1, string name2)
{
    var summaries = /* default list when nothing entered */
    return View(summaries);
}

これもGlobal.asax.csにあります。

    routes.MapRoute(
         "StartBrowse",
         "Gallery/Browse/{s1}/{s2}",
         new
         {
             controller = "Gallery",
             action = "Browse",
             s1 = UrlParameter.Optional,
             s2 = UrlParameter.Optional
         });



    routes.MapRoute(
         "ActualBrowse",
         "Gallery/Browse/{searchterm}",
         new
         {
             controller = "Gallery",
             action = "Browse",
             searchterm=UrlParameter.Optional
         });

回答:


161

1つのコントローラーで同じ名前のアクションメソッドを最大2つだけ持つことができます。そのためには、1つがで[HttpPost]、もう1つがである必要があります[HttpGet]

どちらのメソッドもGETであるため、アクションメソッドの1つを名前変更するか、別のコントローラーに移動する必要があります。

2つのBrowseメソッドは有効なC#オーバーロードですが、MVCアクションメソッドセレクターはどのメソッドを呼び出すかを判断できません。ルートをメソッドに(またはその逆に)一致させようとしますが、このアルゴリズムは強く型付けされていません。

さまざまなアクションメソッドを指すカスタムルートを使用して、必要なことを実行できます。

... Global.asax

routes.MapRoute( // this route must be declared first, before the one below it
     "StartBrowse",
     "Gallery/Browse/Start/Here",
     new
     {
         controller = "Gallery",
         action = "StartBrowse",
     });

routes.MapRoute(
     "ActualBrowse",
     "Gallery/Browse/{searchterm}",
     new
     {
         controller = "Gallery",
         action = "Browse",
         searchterm = UrlParameter.Optional
     });

...そしてコントローラーで...

public ActionResult Browse(string id)
{
    var summaries = /* search using id as search term */
    return View(summaries);
}

public ActionResult StartBrowse()
{
    var summaries = /* default list when nothing entered */
    return View(summaries);
}

また、属性を1つに適用して区別することにより、コントローラー同じ名前のアクションメソッド維持[ActionName]できる場合があります。上記と同じGlobal.asaxを使用すると、コントローラーは次のようになります。

public ActionResult Browse(string id)
{
    var summaries = /* search using id as search term */
    return View(summaries);
}

[ActionName("StartBrowse")]
public ActionResult Browse()
{
    var summaries = /* default list when nothing entered */
    return View(summaries);
}

それで、上記の例で新しいビューを作成する必要がありますか?ActionNameタグを使用しても役に立たないようです。すべてのアクションメソッドの名前を変更するためだけに機能するためです(両方を同時に保持することはできません)。MVCがどのように機能するかを知るのは良いことです。ありがとう。
Dave

6
いいえ、新しいビューを作成する必要はありません。両方のアクションで同じビューを再利用できます。最初の引数としてビュー名を渡すだけreturn View("Browse", summaries);
danludwig

オーバーロードは将来のリリースに含まれる予定ですか?ルートの変更は追加の作業であり、変更を行う場合は追加のメンテナンスが必要です。
Old Geezer

@OldGeezerはおそらくありません。回避策(上記)があり、コントローラーのアクションメソッドがオーバーロードされているのは一般に良い考えではないためです。
danludwig 2015

4

質問がいつ尋ねられたかはわかりませんが、この解決策は利用可能でしたが、使用できます:

Request.QueryString["key"]

したがって、これはあなたの問題に対してうまく機能するはずです:

[HttpGet]
public ActionResult Browse()
{
    if( Request.QueryString["id"] != null )        
        var summaries = /* search using id as search term */
    else /*assuming you don't have any more option*/
        var summaries = /* default list when nothing entered */

    return View(summaries);
} 

2

デフォルトルートの前にRouteConfig.csに次のコードを追加します

routes.MapMvcAttributeRoutes();

そして、コントローラにルート属性を追加します:

    [Route("Cars/deteals/{id:int}")]
    public ContentResult deteals(int id)
    {
        return Content("<b>Cars ID Is " + id + "</b>");
    }

    [Route("Cars/deteals/{name}")]
    public  ContentResult deteals(string name)
    {
        return Content("<b>Car name Is " + name + "</b>");

    }

1

要点は、リクエストクラスを使用してクエリ文字列パラメーターを暗黙的にテストする必要がないということです。

MVCがマッピングを行います(MVCルートに重大な変更を加えた場合を除く)。

したがって、次のアクションリンクパス

/umbraco/Surface/LoginSurface/Logout?DestinationUrl=/home/

パラメータが定義されている(サーフェス)コントローラで自動的に使用できるようになります。

public ActionResult Logout(string DestinationUrl)

MVCが機能します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.