ASP.NET MVC - meneruskan parameter ke pengontrol

105

Saya memiliki pengontrol dengan metode tindakan sebagai berikut:

public class InventoryController : Controller
{
    public ActionResult ViewStockNext(int firstItem)
    {
        // Do some stuff
    }
}

Dan ketika saya menjalankannya saya mendapatkan kesalahan yang menyatakan:

Kamus parameter tidak berisi nilai yang valid dari jenis 'System.Int32' untuk parameter 'firstItem'. Untuk membuat parameter opsional, tipenya harus berupa tipe referensi atau tipe Nullable.

Saya membuatnya berfungsi pada satu titik dan saya memutuskan untuk mencoba fungsi tanpa parameter. Mengetahui bahwa pengontrol tidak gigih, saya memasukkan kembali parameter, sekarang ia menolak untuk mengenali parameter ketika saya memanggil metode tersebut.

Saya menggunakan sintaks url ini untuk memanggil tindakan:

http://localhost:2316/Inventory/ViewStockNext/11

Adakah ide mengapa saya mendapatkan kesalahan ini dan apa yang harus saya lakukan untuk memperbaikinya?

Saya sudah mencoba menambahkan metode lain yang mengambil integer ke kelas itu juga gagal dengan alasan yang sama. Saya sudah mencoba menambahkan satu yang mengambil string, dan string tersebut disetel ke null. Saya sudah mencoba menambahkan satu tanpa parameter dan itu berfungsi dengan baik, tetapi tentu saja itu tidak sesuai dengan kebutuhan saya.

Aneh
sumber

Jawaban:

106

Perutean Anda perlu disiapkan di sepanjang baris {controller}/{action}/{firstItem}. Jika Anda membiarkan perutean sebagai default {controller}/{action}/{id}di global.asax.csfile Anda , maka Anda harus meneruskan id.

routes.MapRoute(
    "Inventory",
    "Inventory/{action}/{firstItem}",
    new { controller = "Inventory", action = "ListAll", firstItem = "" }
);

... atau sesuatu yang mendekati itu.

Jarrett Meyer
sumber
44
Atau cukup ganti nama "firstItem" menjadi "id"
Kyle Trauberman
8
Plus itu dunia lebih bijaksana untuk menambahkan objek kendala ke MapRoute, seperti: new { firstItem = @"\d" }. Dengan cara ini ia hanya akan menerima jika parameternya berupa angka apa pun. Anda dapat memodifikasi regex sesuka Anda, dan bahkan membatasi jumlah desimal, seperti ini: new { firstItem = @"\d{4}" }- sekarang hanya dapat terdiri dari 4 angka. Sunting: contoh MapRoute yang
KristianB
86

Anda dapat mengubah firstItem menjadi id dan itu akan berhasil

Anda dapat mengubah perutean di global.asax (saya tidak merekomendasikannya)

dan, tidak percaya tidak ada yang menyebutkan ini, Anda dapat menghubungi:

http://localhost:2316/Inventory/ViewStockNext?firstItem=11

Dalam @ Url. Tindakan akan menjadi:

@Url.Action("ViewStockNext", "Inventory", new {firstItem=11});

tergantung pada jenis apa yang Anda lakukan, yang terakhir akan lebih cocok. Anda juga harus mempertimbangkan untuk tidak melakukan tindakan ViewStockNext dan sebagai gantinya tindakan ViewStock dengan index. (2 sen saya)

Bart Calixto
sumber
15

Untuk mengubah jawaban Jarret Meyer , Anda perlu mengubah nama parameter menjadi 'id' atau menambahkan rute seperti ini:

routes.MapRoute(
        "ViewStockNext", // Route name
        "Inventory/ViewStockNext/{firstItem}",  // URL with parameters
        new { controller = "Inventory", action = "ViewStockNext" }  // Parameter defaults
    );

Alasannya adalah rute default hanya mencari tindakan tanpa parameter atau parameter bernama 'id'.

Edit: Heh, lupakan Jarret menambahkan contoh rute setelah posting.

Matt Mitchell
sumber
8

atau lakukan dengan Atribut Rute:

public class InventoryController : Controller
{
    [Route("whatever/{firstItem}")]
    public ActionResult ViewStockNext(int firstItem)
    {
        int yourNewVariable = firstItem;
        // ...
    }
}
Yar
sumber
Properti ini mungkin tidak berfungsi dengan versi MVC yang lebih lama.
Suat Atan PhD
Selain itu, agar ini berfungsi, Anda perlu memastikan bahwa Anda telah memanggil routes.MapMvcAttributeRoutes();dalam metode aplikasi RegisterRoutes(RouteCollection)(biasanya di-scaffold ke App_Start \ RouteConfig.cs). Ini mungkin tidak ada di sana secara default.
Daniel Scott
7

Headspring membuat pustaka bagus yang memungkinkan Anda menambahkan alias ke parameter Anda di atribut pada tindakan. Ini terlihat seperti ini:

[ParameterAlias("firstItem", "id", Order = 3)]
public ActionResult ViewStockNext(int firstItem)
{
    // Do some stuff
}

Dengan ini, Anda tidak perlu mengubah perutean hanya untuk menangani nama parameter yang berbeda. Pustaka juga mendukung penerapannya beberapa kali sehingga Anda dapat memetakan beberapa ejaan parameter (berguna saat melakukan pemfaktoran ulang tanpa merusak antarmuka publik Anda).

Anda bisa mendapatkannya dari Nuget dan membaca artikel Jeffrey Palermo tentangnya di sini

Matthew Nichols
sumber
7

public ActionResult ViewNextItem(int? id)membuat idinteger menjadi tipe nullable, tidak perlu konversi string <-> int.

Oskar Duveborn
sumber
3

Menggunakan fitur ASP.NET Core Tag Helper:

<a asp-controller="Home" asp-action="SetLanguage" asp-route-yourparam1="@item.Value">@item.Text</a>
Sasha Yakobchuk
sumber
Ironisnya, jawaban terpendek adalah yang terbaik (yang ini).
1

Ada cara lain untuk mencapai itu (dijelaskan secara lebih rinci dalam contoh Pager Stephen Walther

Pada dasarnya, Anda membuat tautan dalam tampilan:

Html.ActionLink("Next page", "Index", routeData)

Dalam routeData Anda dapat menentukan pasangan nama / nilai (misalnya, routeData ["page"] = 5), dan dalam fungsi Indeks pengontrol parameter yang sesuai menerima nilai. Itu adalah,

public ViewResult Index(int? page)

akan memiliki halaman yang diteruskan sebagai 5. Harus saya akui, sangat tidak biasa bahwa string ("halaman") secara otomatis menjadi variabel - tetapi begitulah cara kerja MVC dalam bahasa lain ...

Felix
sumber
0

Alasan perlakuan khusus dari "id" adalah karena ia ditambahkan ke pemetaan rute default. Untuk mengubahnya, buka Global.asax.cs, dan Anda akan menemukan baris berikut:

routes.MapRoute ("Default", "{controller}/{action}/{id}", 
                 new { controller = "Home", action = "Index", id = "" });

Ubah menjadi:

routes.MapRoute ("Default", "{controller}/{action}", 
                 new { controller = "Home", action = "Index" });
Aristoteles
sumber
0

Atau, Anda dapat mencoba mengubah tipe parameter menjadi string, lalu mengonversi string menjadi integer dalam metode. Saya baru mengenal MVC, tetapi saya yakin Anda memerlukan objek nullable dalam daftar parameter Anda, bagaimana lagi pengontrol akan menunjukkan bahwa tidak ada parameter seperti itu yang diberikan? Begitu...

public ActionResult ViewNextItem(string id)...
RAL
sumber