web-dev-qa-db-ja.com

名前は同じでパラメータが異なるアクションへのルーティング

私はこのルートのセットを持っています:

        routes.MapRoute(
            "IssueType",
            "issue/{type}",
            new { controller = "Issue", action = "Index" }
        );

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

コントローラクラスは次のとおりです。

public class IssueController : Controller
{
    public ActionResult Index()
    {
        // todo: redirect to concrete type
        return View();
    }

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

なぜ、リクエストすると http:// Host/issueThe current request for action 'Index' on controller type 'IssueController' is ambiguous between the following action methods:を取得します
最初の1つのメソッドはパラメーターがない場合に機能し、2番目のメソッドはパラメーターが指定されている場合に機能することを期待しています。

どこで間違えたの?

[〜#〜] upd [〜#〜]:重複の可能性: ASP.NET MVCでコントローラーメソッドをオーバーロードできますか? ==

UPD 2:上記のリンクのため、アクションをオーバーロードさせる合法的な方法はありませんか?

UPD 3:アクションメソッドはパラメーターに基づいてオーバーロードできません(c) http://msdn.Microsoft.com/en-us/ library/system.web.mvc.controller%28VS.100%29.aspx

22
zerkms

有効な型変数を探すIndexメソッドが1つあります

    public class IssueController : Controller  
{  
    public ActionResult Index(string type)  
    {  
        if(string.isNullOrEmpty(type)){
            return View("viewWithOutType");}
        else{
            return View("viewWithType");} 
    }
}

編集:

この投稿のように特定のリクエスト値を探すカスタム属性を作成するのはどうですか StackOverflow

[RequireRequestValue("someInt")] 
public ActionResult MyMethod(int someInt) { /* ... */ } 

[RequireRequestValue("someString")] 
public ActionResult MyMethod(string someString) { /* ... */ } 

public class RequireRequestValueAttribute : ActionMethodSelectorAttribute { 
    public RequireRequestValueAttribute(string valueName) { 
        ValueName = valueName; 
    } 
    public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo) { 
        return (controllerContext.HttpContext.Request[ValueName] != null); 
    } 
    public string ValueName { get; private set; } 
} 
11
Tommy

IDが指定されているかどうかに関係なく、「インデックス」アクションでレンダリングを処理したいという同様の状況に遭遇しました。私が思いついた解決策は、IndexメソッドのIDパラメーターをオプションにすることでした。たとえば、私はもともと両方を持ってみました:

public ViewResult Index()
{
    //...
}
// AND
public ViewResult Index(int entryId)
{
    //...
}

そして、それらを組み合わせて、次のように変更しました。

public ViewResult Index(int entryId = 0)
{
    //...
}
5
jgreg311

2番目のアクションを[HttpPost]でマークするだけです。例えば:

public class IssueController : Controller
{
    public ActionResult Index()
    {
        // todo: redirect to concrete type
        return View();
    }

    [HttpPost]
    public ActionResult Index(string type)
    {
        return View();
    }
}
1
010110110101

リフレクションを使用してパラメーターをチェックするActionFilterAttributeを使用してそれを行うことができます(私はそれを試しました)が、それは悪い考えです。 それぞれの個別のアクションには独自の名前を付ける必要があります。

たとえば、2つのメソッドを「インデックス」と「シングル」と呼んで、名前付けの制限に耐えてみませんか?

一致するシグニチャに基づいてコンパイル時にバインドされるメソッドとは異なり、最後に欠落しているルート値はnullとして扱われます。

パラメータに一致する[hack] ActionFilterAttributeが必要な場合は、私に知らせてください。リンクを投稿しますが、前述のように、それは悪い考えです。

1
Ian Mercer