Mengapa Html.ActionLink menyajikan "? Panjang = 4"

305

Saya SANGAT bingung mengapa kode ini

Html.ActionLink("About", "About", "Home", new { hidefocus = "hidefocus" })

hasil dalam tautan ini:

<a hidefocus="hidefocus" href="/Home/About?Length=4">About</a>

Bagian hidefocusyang ingin saya capai, tetapi dari mana datangnya ?Length=4?

Alter Ego saya
sumber
4
Perilaku ini juga muncul dengan metode Html.BeginForm ().
Jonathon Watney

Jawaban:

326

Panjang = 4 berasal dari upaya untuk membuat serialisasi objek string. Kode Anda menjalankan ActionLinkmetode ini :

public static string ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, object routeValues, object htmlAttributes)

Ini mengambil stringobjek "Home" untuk routeValues, yang dicari oleh pipa MVC untuk properti publik mengubahnya menjadi nilai rute. Dalam kasus stringobjek, satu-satunya properti publik adalah Length, dan karena tidak akan ada rute yang ditentukan dengan parameter Panjang, ia menambahkan nama properti dan nilai sebagai parameter string kueri. Anda mungkin akan menemukan jika Anda menjalankan ini dari halaman yang tidak ada di HomeControllerdalamnya akan menimbulkan kesalahan tentang Aboutmetode tindakan yang hilang . Coba gunakan yang berikut ini:

Html.ActionLink("About", "About", new { controller = "Home" }, new { hidefocus = "hidefocus" })
roryf
sumber
@Blah_Blah hari ini saya tidak menggunakan ini sama sekali, lebih suka menulis tag <a> saya sendiri dan hanya menggunakan Url.Action ("Action", "Controller")
roryf
@roryf jangan khawatir ... ini digunakan dalam tinjauan kode sebagai praktik terbaik, mereka tidak memeriksa tanggal. Seharusnya ada cara untuk memfilter stackoverflow berdasarkan tanggal ...
THBBFT
Jawaban yang bagus Untuk menambahkan ini juga terjadi pada Html.BeginRouteForm untuk alasan yang sama. Html.BeginRouteForm ("Rute", "Action", FormMethod.Post)) Harus Html.BeginRouteForm ("Rute", {action = "AgentSignUp"} baru, FormMethod.Post) yang menghilangkan hal panjang yang aneh
radm4
Juga terjadi dengan Url.Action(). Mengubah dari Url.Action("Action", "Controller", new { area = "" })menjadi Url.Action("Action", new { controller = "Controller", area = "" })menjaga properti Panjang agar tidak muncul.
John Washam
Untuk menghindari situasi semacam itu, Anda selalu dapat menentukan parameter apa yang Anda lewati, seperti:Html.ActionLink("About", "About", "Home", routeValues: null, htmlAttributes: new { hidefocus = "hidefocus" })
Epiplon
195

Cara saya mengatasi ini adalah menambahkan nol ke parameter keempat sebelum deklarasi anonim ( new {}) sehingga menggunakan metode overload berikut: (linkText, actionName, controllerName, routeValues, htmlAttributes):

Html.ActionLink("About", "About", "Home", null, new { hidefocus = "hidefocus" })
Manuel Castro
sumber
Ini adalah jawaban terbaik jika Anda tidak menghubungkan antar Area. Jika Anda perlu menentukan area untuk tautan, Anda harus menentukan nilai routeVile dengan controllerdan areauntuk menjaga properti Length agar tidak muncul di URL.
John Washam
@ JohnWasham Sebenarnya, Anda tidak perlu menentukan controller di routeValuestetapi hanya area. Misalnya:Html.ActionLink("About", "About", "Home", new {@area = "Admin"}, new { hidefocus = "hidefocus" })
Epiplon
1
@epiplon, alasan saya menentukan controller seperti itu adalah karena jika Anda tidak menyertakan htmlAttributes sebagai argumen terakhir ActionLink, MVC akan memasukkan Length=xparameter aneh di akhir URL. Misalnya, letakkan ini di halaman, lalu lihat sumber halaman Anda, dan Anda akan melihat apa yang saya maksud: @Html.ActionLink("About", "About", "Home", new { area = "Admin" }, new { hidefocus = "hidefocus" }) @Html.ActionLink("About", "About", "Home", new { area = "Admin" }) Tetapi jika Anda memasukkan controllerentri di routeValues, itu tidak akan pernah dimasukkan ke Length=xdalam URL.
John Washam
@epiplon, Anda juga tidak perlu menggunakan @di @area = "Admin", supaya kau tahu.
John Washam
88

Anda lupa menambahkan parm HTMLAttributes.

Ini akan berfungsi tanpa perubahan:

Html.ActionLink("About", "About", "Home", new { hidefocus = "hidefocus" },null)
Jesse Rose
sumber
Saya tidak tahu, mengapa ini tidak berhasil untuk saya. Saya mencoba dengan "new {hidefocus =" "}", Dan ini bekerja untuk saya.
Naredla Nithesh Reddy
28

Parameter untuk ActionLink tidak benar, itu berusaha untuk menggunakan nilai "Rumah" sebagai nilai rute, bukan tipe anonim.

Saya yakin Anda hanya perlu menambahkan new { }ataunull sebagai parameter terakhir.

EDIT: Cukup baca kembali posting dan sadari Anda mungkin ingin menentukan nol sebagai parameter terakhir kedua, bukan yang terakhir.


sumber
1
BTW Mereka harus menghapus satu metode karena tidak mungkin menggunakannya!
Marc Climent
5
Html.ActionLink("About", "About", "Home", new { hidefocus = "hidefocus" }, new { })

Ini akan mengambil kelebihan: string linkText, string actionName, string controllerName, Object routeValues, Object htmlAttributes

pengguna2254436
sumber
3

Mohon gunakan metode overload kanan dengan lima (5) parameter. Contoh:

@using (@Ajax.BeginForm("Register", "Account", null,
    new AjaxOptions
    {
        HttpMethod = "POST",
        OnSuccess = "OnSuccess",
        OnFailure = "OnFailure",
        OnBegin = "OnBegin",
        OnComplete = "OnComplete"
    }, new { @class = "form-login" }))
Omveer singh maurya
sumber
menambahkan null setelah nama pengontrol sangat membantu dalam kasus saya.
Munam Yousuf
Ini adalah jawaban yang sama efektifnya dengan jawaban @ Jesse dengan bonus tambahan yang mencakup versi Ajax, yang bukan yang diminta OP, tetapi terkait dengan masalah yang sama.
gcoulby
2

Hapus "Rumah" (nama pengontrol) sehingga kodenya adalah:

Html.ActionLink("About", "About", new { hidefocus = "hidefocus" })
Fil
sumber
1

Dengan nama atribut:

 @Html.ActionLink(linkText: "SomeText", actionName: "SomeAction", controllerName: "SomeControllerName", routeValues: new { parameterName = parameterValue}, htmlAttributes: null)
BermanfaatBee
sumber
0

Seperti yang ditunjukkan Jonathon Watney dalam komentar, ini juga berlaku untuk

Html.BeginForm ()

metode. Dalam kasus saya, saya berada di Create.cshtml menargetkan permintaan posting dari controller yang sesuai + Buat tindakan dan punya

using (Html.BeginForm("Create")) {
  @Html.AntiForgeryToken()
  ...
}

yang menambahkan querystring "? Panjang = 6" ke tindakan bentuk saat diberikan. Diisyaratkan oleh jawaban yang disetujui roryf dan menyadari panjang string "Buat" adalah 6, saya akhirnya menyelesaikan ini dengan menghapus spesifikasi tindakan eksplisit:

using (Html.BeginForm()) {
      @Html.AntiForgeryToken()
      ...
    }
Frederik Struck-Schøning
sumber
0

Mungkin orang lain memiliki masalah yang sama dan perlu menyediakan nilai kelas melalui parm HTMLAttributes . Inilah solusi saya:

@Html.ActionLink("About", "About", new { controller = "Home", area = "" }, new { hidefocus = "hidefocus", @class = "nav-item nav-link" })

Taersious
sumber
0

Mencari jawaban untuk pertanyaan saya mendarat saya di sini, pada dasarnya itu adalah pilihan kelebihan yang benar @Html.ActionLink masukkan deskripsi gambar di sini yang penting.
Saya memilih kelebihan yang tidak ada, ( tanpa yang terakhir null ), danMVC tidak memiliki overload seperti itu, menghasilkan URL palsu seperti yang disebutkan OP.

Catatan pribadi : Anda dapat menggunakan usejenis anonim tidak berarti Anda dapat menggunakan kelebihan beban mana pun - yang tidak ada? - pastikan: itu memiliki didefinisikan!
- Datang ke sini pada masa MVC 5.2

Irf
sumber