339

ASP.NET MVC でコントローラー メソッドをオーバーロードできるかどうかを知りたいです。試行するたびに、以下のエラーが発生します。2 つのメソッドは異なる引数を受け入れます。これは仕方のないことでしょうか?

コントローラー タイプ 'MyController' のアクション 'MyMethod' に対する現在の要求は、次のアクション メソッド間であいまいです:

4

18 に答える 18

207

コードでオーバーロードを行う場合は、属性を使用できます。

[ActionName("MyOverloadedName")]

ただし、同じ http メソッドには別のアクション名を使用する必要があります (他の人が言っているように)。したがって、それはその時点での単なるセマンティクスです。コードと属性のどちらに名前を入れますか?

Phil にはこれに関連する記事があります: http://haacked.com/archive/2008/08/29/how-a-method-becomes-an-action.aspx

于 2009-01-12T20:37:43.083 に答える
70

はい。HttpGetこれは、各コントローラー メソッドの/ HttpPost(または同等のAcceptVerbs属性) を別のもの、つまりHttpGetorに設定することで実現できましたが、HttpPost両方には設定できませんでした。そうすれば、リクエストのタイプに基づいて、どのメソッドを使用するかを判断できます。

[HttpGet]
public ActionResult Show()
{
   ...
}

[HttpPost]
public ActionResult Show( string userName )
{
   ...
}

私が持っている 1 つの提案は、このような場合、コードの重複を避けるために両方のパブリック Action メソッドが依存するプライベート実装を持つことです。

于 2009-01-12T20:33:55.463 に答える
44

他にできることは次のとおりです...パラメーターを持つことができるメソッドとできないメソッドが必要です。

これを試してみませんか...

public ActionResult Show( string username = null )
{
   ...
}

これは私にとってはうまくいきました...そして、この1つの方法で、実際に着信パラメーターがあるかどうかをテストできます。


文字列の無効な null 許容構文を削除し、既定のパラメーター値を使用するように更新されました。

于 2011-03-29T06:22:27.750 に答える
23

いいえ、いいえ、いいえ。「LoadCustomer」がオーバーロードされている以下のコントローラー コードを試してみてください。

public class CustomerController : Controller
    {
        //
        // GET: /Customer/

        public ActionResult LoadCustomer()
        {
            return Content("LoadCustomer");
        }
        public ActionResult LoadCustomer(string str)
        {
            return Content("LoadCustomer with a string");
        }
    }

「LoadCustomer」アクションを呼び出そうとすると、次の図に示すようなエラーが発生します。

ここに画像の説明を入力

ポリモーフィズムは C# プログラミングの一部ですが、HTTP はプロトコルです。HTTP はポリモーフィズムを理解していません。HTTP は概念または URL で機能し、URL は一意の名前のみを持つことができます。したがって、HTTP はポリモーフィズムを実装していません。

これを修正するには、「ActionName」属性を使用する必要があります。

public class CustomerController : Controller
    {
        //
        // GET: /Customer/

        public ActionResult LoadCustomer()
        {
            return Content("LoadCustomer");
        }

        [ActionName("LoadCustomerbyName")]
        public ActionResult LoadCustomer(string str)
        {
            return Content("LoadCustomer with a string");
        }
    }

したがって、URL「Customer/LoadCustomer」を呼び出すと、「LoadCustomer」アクションが呼び出され、URL 構造「Customer/LoadCustomerByName」で「LoadCustomer(string str)」が呼び出されます。

ここに画像の説明を入力

ここに画像の説明を入力

このコードプロジェクトの記事から取った上記の回答 --> MVC アクションのオーバーロード

于 2014-11-27T23:48:25.570 に答える
15

この問題を克服するために、 for each アクションを調べてポストされた Form 値と比較し、フォーム値が一致しないメソッドを拒否する を書くことができます (もちろん、ボタン名は除きます)。ActionMethodSelectorAttributeMethodInfo

例を次に示します

しかし、これは良い考えではありません。

于 2010-02-17T01:09:53.867 に答える
14

私の知る限り、異なる http メソッドを使用する場合は、同じメソッドしか使用できません。

すなわち

[AcceptVerbs("GET")]
public ActionResult MyAction()
{

}

[AcceptVerbs("POST")]
public ActionResult MyAction(FormResult fm)
{

}
于 2009-01-12T20:33:28.723 に答える
10

MVC5の属性ルーティングの助けを借りてこれを達成しました。確かに、私は WebForms を使用した 10 年間の Web 開発から来て、MVC を初めて使用しましたが、次の方法でうまくいきました。受け入れられた回答とは異なり、これにより、オーバーロードされたすべてのアクションを同じビュー ファイルでレンダリングできます。

まず、App_Start/RouteConfig.cs で属性ルーティングを有効にします。

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapMvcAttributeRoutes();

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );            
    }
}

必要に応じて、コントローラー クラスをデフォルトのルート プレフィックスで装飾します。

[RoutePrefix("Returns")]
public class ReturnsController : BaseController
{
    //.......

次に、共通のルートとパラメーターを使用して相互にオーバーロードするコントローラー アクションを装飾します。型制約パラメーターを使用すると、異なる型の ID で同じ URI 形式を使用できます。

[HttpGet]
// Returns
public ActionResult Index()
{
    //.....
}

[HttpGet]
[Route("View")]
// Returns/View
public ActionResult View()
{
    // I wouldn't really do this but it proves the concept.
    int id = 7026;
    return View(id);
}

[HttpGet]
[Route("View/{id:int}")]
// Returns/View/7003
public ActionResult View(int id)
{
    //.....
}

[HttpGet]
[Route("View/{id:Guid}")]
// Returns/View/99300046-0ba4-47db-81bf-ba6e3ac3cf01
public ActionResult View(Guid id)
{
    //.....
}

これが助けになり、誰かを間違った道に導いていないことを願っています. :-)

于 2015-06-03T09:32:36.560 に答える
5

ActionResultと の両方を処理するためPostに単一を使用できますGet

public ActionResult Example() {
   if (Request.HttpMethod.ToUpperInvariant() == "GET") {
    // GET
   }
   else if (Request.HttpMethod.ToUpperInvariant() == "POST") {
     // Post  
   }
}

GetPostメソッドのシグネチャが一致する場合に便利です。

于 2012-12-03T14:18:52.963 に答える
2

次のオーバーロードが必要でした:

public ActionResult Index(string i);
public ActionResult Index(int groupId, int itemId);

私がこれを行うことになったのに十分な議論はほとんどありませんでした:

public ActionResult Index(string i, int? groupId, int? itemId)
{
    if (!string.IsNullOrWhitespace(i))
    {
        // parse i for the id
    }
    else if (groupId.HasValue && itemId.HasValue)
    {
        // use groupId and itemId for the id
    }
}

特に多くの議論がある場合、これは完璧な解決策ではありませんが、私にとってはうまくいきます。

于 2013-06-10T21:57:00.233 に答える
1

私のアプリケーションでも同じ問題に直面しました。メソッド情報を変更せずに、アクション ヘッドに [ActionName("SomeMeaningfulName")] を指定しました。問題は解決された

[ActionName("_EmployeeDetailsByModel")]
        public PartialViewResult _EmployeeDetails(Employee model)
        {
            // Some Operation                
                return PartialView(model);
            }
        }

[ActionName("_EmployeeDetailsByModelWithPagination")]
        public PartialViewResult _EmployeeDetails(Employee model,int Page,int PageSize)
        {

                // Some Operation
                return PartialView(model);

        }
于 2016-05-27T11:43:29.350 に答える
0

別のスレッドに投稿されたこの回答が好きです

これは主に、別のコントローラーから継承し、ベース コントローラーからのアクションをオーバーライドする場合に使用されます。

ASP.NET MVC - 異なるパラメーターでアクションをオーバーライドする

于 2013-07-02T11:52:01.610 に答える
0
  1. 同じ問題に苦しんでいる人のためのこの答え。ActionMethodSelectorAttribute に基づいて独自のカスタム フィルターを実装できます。ここで、あなたの質問を解決するための最良の解決策を見つけました。.net 5 プロジェクトで正常に動作します。

  2. Web API コントローラーと同じロジックを実装しようとする場合は、Microsoft.AspNetCore.Mvc.WebApiCompatShim を使用します。この nuget パッケージは、ASP.NET Core MVC と ASP.NET Web API 2 との互換性を提供し、既存の Web API 実装の移行を簡素化します。この回答を確認してください。ただし、ASP.NET Core 3.0 以降、Microsoft.AspNetCore.Mvc.WebApiCompatShim パッケージは利用できなくなっていることを考慮してください。

于 2021-05-27T12:03:31.093 に答える
0

基本メソッドを仮想として作成する

public virtual ActionResult Index()

オーバーライドされたメソッドをオーバーライドとして作成します

public override ActionResult Index()

編集:これは明らかに、オーバーライド メソッドが OP の意図ではないように見える派生クラスにある場合にのみ適用されます。

于 2012-02-28T14:40:51.077 に答える
-1

これが、異なるモデルの複数のアクションに POST する複数のビューに対して 1 つの GET アクションを使用しようとする場合は、最初の GET にリダイレクトする POST アクションごとに GET アクションを追加して、更新時の 404 を防止してください。

ロングショットだが一般的なシナリオ。

于 2016-09-12T16:19:58.380 に答える