ทำไม Html.ActionLink จึงแสดงผล“? Length = 4”


305

ฉันสับสนมากว่าทำไมรหัสนี้

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

ผลลัพธ์ในลิงค์นี้:

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

hidefocusส่วนหนึ่งเป็นสิ่งที่ผมมุ่งมั่นที่จะประสบความสำเร็จ แต่ที่ใด?Length=4มาจากไหน?


4
พฤติกรรมนี้ยังปรากฏขึ้นพร้อมกับวิธีการ Html.BeginForm ()
Jonathon Watney

คำตอบ:


326

ความยาว = 4 มาจากความพยายามในการทำให้วัตถุสตริงเป็นอนุกรม รหัสของคุณใช้ActionLinkวิธีนี้:

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

สิ่งนี้จะนำstringวัตถุ "บ้าน" สำหรับค่าเส้นทางซึ่งการประปา MVC ค้นหาคุณสมบัติสาธารณะเปลี่ยนเป็นค่าเส้นทาง ในกรณีของstringวัตถุทรัพย์สินสาธารณะเพียงอย่างเดียวคือLengthและเนื่องจากจะไม่มีเส้นทางที่กำหนดไว้ด้วยพารามิเตอร์ Length ซึ่งจะเพิ่มชื่อและค่าของคุณสมบัติเป็นพารามิเตอร์สตริงแบบสอบถาม คุณอาจพบว่าหากคุณเรียกใช้จากหน้าเว็บที่ไม่ได้อยู่ในหน้าHomeControllerนั้นจะทำให้เกิดข้อผิดพลาดเกี่ยวกับAboutวิธีการทำงานที่ขาดหายไป ลองใช้สิ่งต่อไปนี้:

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

@Blah_Blah ทุกวันนี้ฉันไม่ได้ใช้สิ่งนี้เลยโปรดเขียนแท็ก <a> ของตัวเองและใช้ Url.Action ("Action", "Controller")
roryf

@Roryf ไม่ต้องกังวล ... นี่ใช้ในการตรวจสอบโค้ดเพื่อเป็นแนวทางปฏิบัติที่ดีที่สุดพวกเขาไม่ได้ตรวจสอบวันที่ ควรมีวิธีในการกรอง stackoverflow ตามวันที่ ...
THBBFT

คำตอบที่ดี เพียงแค่เพิ่มสิ่งนี้ยังเกิดขึ้นใน Html.BeginRouteForm ด้วยเหตุผลเดียวกัน Html.BeginRouteForm ("เส้นทาง", "การกระทำ", FormMethod.Post)) ควรเป็น Html.BeginRouteForm ("เส้นทาง", ใหม่ {action = "AgentSignUp"}, FormMethod.Post) ที่กำจัดสิ่งที่มีความยาวแปลก ๆ
radm4

Url.Action()นอกจากนี้ยังเกิดขึ้นกับ การเปลี่ยนจากUrl.Action("Action", "Controller", new { area = "" })เป็นไม่Url.Action("Action", new { controller = "Controller", area = "" })ให้คุณสมบัติความยาวปรากฏขึ้น
John Washam

เพื่อหลีกเลี่ยงสถานการณ์เหล่านั้นคุณสามารถระบุพารามิเตอร์ที่คุณกำลังจะผ่านได้เช่น:Html.ActionLink("About", "About", "Home", routeValues: null, htmlAttributes: new { hidefocus = "hidefocus" })
Epiplon

195

วิธีที่ฉันแก้ไขสิ่งนี้คือการเพิ่ม null ให้กับพารามิเตอร์ที่สี่ก่อนการประกาศที่ไม่ระบุชื่อ ( new {}) เพื่อให้ใช้เมธอด overload ดังต่อไปนี้: (linkText, actionName, controllerName, routeValues, htmlAttributes):

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

นี่คือคำตอบที่ดีที่สุดหากคุณไม่ได้เชื่อมโยงระหว่างพื้นที่ หากคุณต้องการระบุพื้นที่สำหรับลิงค์คุณจะต้องระบุ routeValues ​​พร้อมกับcontrollerและareaเพื่อให้คุณสมบัติความยาวไม่แสดงใน URL
John Washam

@JohnWasham ที่จริงแล้วคุณไม่จำเป็นต้องระบุคอนโทรลเลอร์ในrouteValuesแต่เฉพาะพื้นที่ ตัวอย่างเช่น:Html.ActionLink("About", "About", "Home", new {@area = "Admin"}, new { hidefocus = "hidefocus" })
Epiplon

1
@epiplon เหตุผลที่ฉันระบุคอนโทรลเลอร์เช่นนั้นเป็นเพราะถ้าคุณไม่ได้รวม htmlAttributes เป็นอาร์กิวเมนต์สุดท้ายของActionLinkMVC จะรวมLength=xพารามิเตอร์แปลก ๆไว้ท้าย URL ตัวอย่างเช่นวางสิ่งนี้ลงบนหน้าเว็บจากนั้นดูที่มาของหน้าเว็บของคุณแล้วคุณจะเห็นว่าฉันหมายถึงอะไร: @Html.ActionLink("About", "About", "Home", new { area = "Admin" }, new { hidefocus = "hidefocus" }) @Html.ActionLink("About", "About", "Home", new { area = "Admin" }) แต่ถ้าคุณใส่ข้อความลงไปcontrollerในสิ่งrouteValuesนั้นมันจะไม่ใส่Length=xใน URL เลย
John Washam

@epiplon คุณยังไม่จำเป็นต้องใช้@ในการ@area = "Admin"เพียงเพื่อให้คุณรู้ว่า
John Washam

88

คุณลืมที่จะเพิ่ม HTMLAttributes parm

สิ่งนี้จะทำงานโดยไม่มีการเปลี่ยนแปลงใด ๆ :

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

ฉันไม่รู้ว่าทำไมจึงไม่ได้ผลสำหรับฉันฉันลองใช้ "new {hidefocus =" "}" และนี่ใช้งานได้สำหรับฉัน
Naredla Nithesh Reddy

28

พารามิเตอร์ของ ActionLink ไม่ถูกต้องกำลังพยายามใช้ค่า "Home" เป็นค่าเส้นทางแทนที่จะเป็นประเภทที่ไม่ระบุตัวตน

ฉันเชื่อว่าคุณเพียงแค่ต้องเพิ่มnew { }หรือnullเป็นพารามิเตอร์สุดท้าย

แก้ไข: เพียงแค่อ่านโพสต์ใหม่และรู้ว่าคุณอาจต้องการระบุโมฆะเป็นพารามิเตอร์ตัวที่สองไม่ใช่ตัวสุดท้าย


1
BTW พวกเขาควรลบวิธีหนึ่งเนื่องจากไม่สามารถใช้มันได้!
Marc Climent

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

สิ่งนี้จะใช้โอเวอร์โหลด: string linkText, สตริง actionName, ตัวควบคุมสตริง, ค่าเส้นทางของเส้นทาง, ค่าวัตถุ htmlAttributes


3

โปรดใช้วิธีการโอเวอร์โหลดที่เหมาะสมพร้อมกับพารามิเตอร์ห้า (5) ตัว ตัวอย่าง:

@using (@Ajax.BeginForm("Register", "Account", null,
    new AjaxOptions
    {
        HttpMethod = "POST",
        OnSuccess = "OnSuccess",
        OnFailure = "OnFailure",
        OnBegin = "OnBegin",
        OnComplete = "OnComplete"
    }, new { @class = "form-login" }))

เพิ่มnullหลังจากชื่อคอนโทรลเลอร์มีประโยชน์ในกรณีของฉัน
Munam Yousuf

นี่เป็นคำตอบเดียวกับคำตอบของ @ Jesse พร้อมกับโบนัสเพิ่มเติมที่ครอบคลุมถึงเวอร์ชัน Ajax ซึ่งไม่ใช่สิ่งที่ OP ร้องขอ แต่เกี่ยวข้องกับปัญหาเดียวกัน
gcoulby

2

เพียงแค่ลบ "บ้าน" (ชื่อของตัวควบคุม) เพื่อให้รหัสจะ:

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

1

ด้วยชื่อคุณลักษณะ:

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

0

ในฐานะที่เป็น Jonathon Watney ชี้ให้เห็นในความคิดเห็นนี้ก็ไป

Html.BeginForm ()

วิธีการ ในกรณีของฉันฉันอยู่ในCreate.cshtmlกำหนดเป้าหมายคำขอโพสต์ของตัวควบคุมที่เกี่ยวข้อง + สร้างการกระทำและมี

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

ซึ่งเพิ่มการสอบถาม"? Length = 6"ในการดำเนินการแบบฟอร์มเมื่อแสดงผล คำแนะนำที่ได้รับอนุมัติจาก roryf และตระหนักถึงความยาวสตริงของ "สร้าง" คือ 6 ในที่สุดฉันก็แก้ไขได้โดยลบข้อกำหนดการดำเนินการที่ชัดเจน:

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

0

บางทีคนอื่นอาจมีปัญหาเดียวกันและจำเป็นต้องให้ค่าคลาสผ่านHTMLAttributes parm นี่คือทางออกของฉัน:

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


0

ค้นหาคำตอบสำหรับคำถามของฉันที่มาถึงฉันที่นี่โดยทั่วไปคือการเลือกโอเวอร์โหลดที่ถูกต้อง@Html.ActionLink ป้อนคำอธิบายรูปภาพที่นี่ ซึ่งมีความสำคัญ
ฉันเลือกโอเวอร์โหลดที่ไม่มีอยู่ ( โดยไม่ใช้ตัวสุดท้าย null ) และMVCไม่มีการโอเวอร์โหลดดังกล่าวส่งผลให้เกิด URL ที่ผิดพลาดอย่างที่ OP กล่าวถึง

บันทึกส่วนตัว:คุณสามารถuseระบุชื่อประเภทไม่ได้หมายความว่าคุณสามารถใช้เกินพิกัดที่ไม่มีอยู่ได้? - ตรวจสอบให้แน่ใจ: มัน มีการกำหนดไว้!
- มาที่นี่ในเวลาของ MVC 5.2

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.