Perutean: Permintaan tindakan saat ini […] tidak jelas antara metode tindakan berikut

100

Saya memiliki View bernama Browse.chtml, di mana pengguna dapat memasukkan istilah pencarian, atau membiarkan istilah pencarian kosong. Saat memasukkan istilah pencarian, saya ingin mengarahkan halaman ke http://localhost:62019/Gallery/Browse/{Searchterm} dan ketika tidak ada yang dimasukkan, saya ingin mengarahkan browser ke http://localhost:62019/Gallery/Browse/Start/Here.

Ketika saya mencoba ini, saya mendapatkan kesalahan:

Permintaan saat ini untuk tindakan 'Jelajahi' pada jenis pengontrol 'GalleryController' ambigu di antara metode tindakan berikut: System.Web.Mvc.ActionResult Browse (System.String) pada tipe AutoApp_MVC.Controllers.GalleryController System.Web.Mvc.ActionResult Browse (Int32, System.String) pada tipe AutoApp_MVC.Controllers.GalleryController

Semua yang saya lakukan dengan MVC adalah untuk pertama kalinya. Saya tidak yakin apa lagi yang harus dicoba saat ini.

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

Saya juga punya ini di 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
         });
Dave
sumber

Jawaban:

161

Anda hanya dapat memiliki maksimal 2 metode tindakan dengan nama yang sama pada pengontrol, dan untuk melakukan itu, 1 harus [HttpPost], dan yang lainnya harus [HttpGet].

Karena kedua metode Anda adalah GET, Anda harus mengganti nama salah satu metode tindakan atau memindahkannya ke pengontrol yang berbeda.

Meskipun 2 metode Jelajah Anda merupakan kelebihan C # yang valid, pemilih metode tindakan MVC tidak dapat mengetahui metode mana yang akan dipanggil. Ini akan mencoba mencocokkan rute ke metode (atau sebaliknya), dan algoritme ini tidak diketik dengan kuat.

Anda dapat mencapai apa yang Anda inginkan menggunakan rute khusus yang menunjuk ke metode tindakan yang berbeda:

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

... dan di pengontrol ...

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

Anda mungkin juga bisa mempertahankan metode tindakan yang dinamai sama di pengontrol , dengan menerapkan [ActionName]atribut ke salah satu untuk membedakannya. Menggunakan Global.asax yang sama seperti di atas, pengontrol Anda akan terlihat seperti ini:

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);
}
danludwig
sumber
Jadi, saya perlu membuat tampilan baru dalam contoh Anda di atas? Sepertinya itu tidak membantu untuk menggunakan tag ActionName, karena saya pikir itu hanya berfungsi untuk mengganti nama semua metode tindakan (tidak dapat menyimpan keduanya pada saat yang sama). Senang rasanya mengetahui cara kerja MVC. Terima kasih.
Dave
6
Tidak, Anda tidak perlu membuat tampilan baru. Anda masih dapat menggunakan kembali tampilan yang sama untuk kedua tindakan. return View("Browse", summaries);
Sampaikan
Apakah kelebihan beban akan disertakan dalam beberapa rilis mendatang? Mengubah rute merupakan pekerjaan tambahan dan pemeliharaan tambahan diperlukan saat perubahan dilakukan.
Kakek Tua
@OldGeezer mungkin tidak, karena ada solusi (di atas), dan karena metode tindakan yang kelebihan beban dalam pengontrol umumnya bukan ide yang baik.
danludwig
4

Saya tidak tahu kapan pertanyaan itu diajukan, solusi ini tersedia tetapi Anda dapat menggunakan:

Request.QueryString["key"]

Jadi ini seharusnya berfungsi dengan baik untuk masalah Anda:

[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);
} 
Saygın Doğu
sumber
2

Tambahkan kode berikut di RouteConfig.cs sebelum rute default

routes.MapMvcAttributeRoutes();

Dan tambahkan atribut rute di pengontrol seperti:

    [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>");

    }
omar mohameed
sumber
1

Saya pikir poin yang dibuat adalah Anda tidak perlu menguji secara implisit untuk parameter querystring menggunakan kelas permintaan.

MVC melakukan pemetaan untuk Anda (kecuali Anda telah membuat perubahan besar pada rute MVC Anda).

Jadi jalur tautan tindakan

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

akan secara otomatis tersedia untuk pengontrol (permukaan) Anda dengan parameter yang ditentukan:

public ActionResult Logout(string DestinationUrl)

MVC melakukan pekerjaannya.

Jalan Darren
sumber