2012-05-19 64 views
69

Browse.chtmlと呼ばれるビューがあります。ユーザーは検索語を入力したり、検索語を空白のままにしたりできます。検索語を入力するときには、ページをhttp://localhost:62019/Gallery/Browse/{Searchterm}に送りたいと思います。何も入力しなかった場合は、ブラウザをhttp://localhost:62019/Gallery/Browse/Start/Hereにします。ルーティング:現在のアクション要求[...]は、次のアクションメソッド間であいまいです

私はこれをしようとすると、私はエラーを取得する:私はMVCでやっている

The current request for action 'Browse' on controller type 'GalleryController' is ambiguous between the following action methods: System.Web.Mvc.ActionResult Browse(System.String) on type AutoApp_MVC.Controllers.GalleryController System.Web.Mvc.ActionResult Browse(Int32, System.String) on type AutoApp_MVC.Controllers.GalleryController

すべてが初めてです。私はこの時点で他に何を試していいのか分かりません。

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 
     }); 

答えて

119

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

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

2ブラウズメソッドが有効な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); 
} 

また、[ActionName]属性を区別するために適用することで、keep the action methods named the same in the controllerにすることもできます。上記と同じの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); 
} 
+0

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

+5

いいえ、新しいビューを作成する必要はありません。両方の操作で同じビューを再利用することはできます。 'return view(" Browse "、要約)の最初の引数としてビュー名を渡してください; – danludwig

+0

素晴らしい、ありがとう。 – Dave

3

質問は、このソリューションが利用可能でしたが、あなたが使用することができ頼まれたとき、私は知らない。

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); 
} 
1

私が作られているポイントは、あなたが暗黙的に要求クラスを使用してクエリ文字列パラメータをテストする必要がないということだと思います。

MVCがあなたのためのマッピングを行います(MVCルートに大きな変更を加えていない限り)。

したがって

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

のActionLinkのパスが自動的に定義されたパラメータを使用して(表面)コントローラに利用可能である:

public ActionResult Logout(string DestinationUrl) 

MVCは、作業を行います。

関連する問題