วิธี HTML.ActionLink


249

สมมติว่าฉันมีชั้นเรียน

public class ItemController:Controller
{
    public ActionResult Login(int id)
    {
        return View("Hi", id);
    }
}

ในหน้าเว็บที่ไม่ได้อยู่ที่โฟลเดอร์รายการที่ItemControllerอยู่ฉันต้องการสร้างลิงค์ไปยังLoginวิธีการ ดังนั้นHtml.ActionLinkฉันควรใช้วิธีใดและฉันควรผ่านพารามิเตอร์ใด

โดยเฉพาะฉันกำลังมองหาวิธีการเปลี่ยน

Html.ActionLink(article.Title,
    new { controller = "Articles", action = "Details",
          id = article.ArticleID })

ที่ถูกยกเลิกในการแปลง MVC แบบ ASP.NET ล่าสุด


17
เอกสารประกอบสำหรับผู้ที่มองหา: msdn.microsoft.com/en-us/library/ …
BlueRaja - Danny Pflughoeft

@ Danny ขอบคุณกำลังค้นหาบน Google เมื่อฉันลงเอยที่นี่
Rei Miyasaka

คำตอบ:


491

ฉันคิดว่าสิ่งที่คุณต้องการคือ:

ASP.NET MVC1

Html.ActionLink(article.Title, 
                "Login",  // <-- Controller Name.
                "Item",   // <-- ActionMethod
                new { id = article.ArticleID }, // <-- Route arguments.
                null  // <-- htmlArguments .. which are none. You need this value
                      //     otherwise you call the WRONG method ...
                      //     (refer to comments, below).
                )

วิธีนี้ใช้ลายเซ็น ActionLink ของวิธีต่อไปนี้:

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

ASP.NET MVC2

มีการโต้แย้งกันสองครั้ง

Html.ActionLink(article.Title, 
                "Item",   // <-- ActionMethod
                "Login",  // <-- Controller Name.
                new { id = article.ArticleID }, // <-- Route arguments.
                null  // <-- htmlArguments .. which are none. You need this value
                      //     otherwise you call the WRONG method ...
                      //     (refer to comments, below).
                )

วิธีนี้ใช้ลายเซ็น ActionLink ของวิธีต่อไปนี้:

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

ASP.NET MVC3 +

อาร์กิวเมนต์อยู่ในลำดับเดียวกันกับ MVC2 อย่างไรก็ตามไม่จำเป็นต้องใช้ค่า id อีกต่อไป:

Html.ActionLink(article.Title, 
                "Item",   // <-- ActionMethod
                "Login",  // <-- Controller Name.
                new { article.ArticleID }, // <-- Route arguments.
                null  // <-- htmlArguments .. which are none. You need this value
                      //     otherwise you call the WRONG method ...
                      //     (refer to comments, below).
                )

นี่เป็นการหลีกเลี่ยงการเข้ารหัสโลจิกการกำหนดเส้นทางใด ๆ ลงในลิงก์อย่างหนัก

 <a href="/Item/Login/5">Title</a> 

นี่จะให้ผลลัพธ์ html ต่อไปนี้ของคุณโดยสมมติว่า:

  1. article.Title = "Title"
  2. article.ArticleID = 5
  3. คุณยังคงกำหนดเส้นทางต่อไปนี้ไว้

. .

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

7
แต่นี่ไม่ได้ให้ URL เหมือน / Item / Login ใช่ไหม id = 5?
Adhip Gupta

21
มีอะไรที่แปลกคือถ้าคุณพลาดพารามิเตอร์สุดท้ายมันผนวกสำหรับฉันความยาว = 8 การกระทำปัจจุบันหรือไม่?
คริส S

32
@Chris S - ฉันรู้ว่านี่คือโพสต์เก่า แต่เหตุผลสำหรับ? ความยาว = 8 เป็นเพราะคุณต้องมี, nullพารามิเตอร์หลังจากที่คุณnew { ... }... เพราะถ้าคุณตรวจสอบการโอเวอร์โหลดของวิธีการนั้นมันคิดว่าพารามิเตอร์ของคุณเป็น htmlArguments ... ไม่ใช่การโต้แย้งเส้นทาง ในการใช้วิธีการที่ถูกต้องคุณจำเป็นต้องใช้วิธีการที่มีrouteArguments, htmlArguments.. ดังนั้นเพียงผ่านเป็นโมฆะสำหรับที่ผ่านhtmlArgumentมา ส่วนแรกของรหัสในการตอบกลับนี้คือมัน ฉันได้อัปเดตโพสต์นี้เพื่อให้คุณเห็นได้อย่างง่ายดาย (เช่นมันไม่ได้เลื่อน)
Pure.Krome

7
มีใครลองกับ MVC 3 บ้างไหม? ดูเหมือนว่าบรรทัด ControllerName และ ActionMethod ในตัวอย่างด้านบนพลิกแล้ว มีคนอื่นเห็นอีกไหม?
Steve Duitsman

8
ใน MVC3 ไม่พบคุณสมบัติ id ... ควรใช้สิ่งต่อไปนี้แทน:@Html.ActionLink("Text","Action","Controller", new { item.ID }, null)
Gavin Coates

30

ผมอยากจะเพิ่มคำตอบของโจเซฟ Kingry เขาจัดหาวิธีแก้ปัญหา แต่ในตอนแรกฉันไม่สามารถทำงานได้และได้ผลลัพธ์เช่นเดียวกับ Adhip Gupta จากนั้นฉันก็รู้ว่าเส้นทางต้องมีอยู่ในที่แรกและพารามิเตอร์ต้องตรงกับเส้นทางอย่างแน่นอน ดังนั้นฉันจึงมี ID และพารามิเตอร์ข้อความสำหรับเส้นทางของฉันซึ่งจำเป็นต้องรวมไว้ด้วย

Html.ActionLink(article.Title, "Login", "Item", new { id = article.ArticleID, title = article.Title }, null)

4
นี่คือสิ่งที่ฉันต้องการ - ฉันลืมที่จะเพิ่มอาร์กิวเมนต์โมฆะสุดท้าย ขอบคุณ
Ian Oxley

1
ขอบคุณที่แสดงการแมปจากชื่อพารามิเตอร์เส้นทางเช่นกัน (ใหม่ {id = ... , bar = ... }.
William Rose

17

คุณอาจต้องการดูRouteLink()วิธีการวิธีนี้ช่วยให้คุณระบุทุกอย่าง (ยกเว้นข้อความลิงค์และชื่อเส้นทาง) ผ่านพจนานุกรม


4
จะดีมากหากได้เห็นตัวอย่างของวิธีการแก้ไขปัญหา หน้า MSDN มีการโอเวอร์โหลดจำนวนมากและการรู้ว่าสิ่งที่ควรมองหาอาจทำให้เกิดความสับสน
Simon Martin

14

ฉันคิดว่าโจเซฟพลิกผู้ควบคุมและแอ็คชั่น ก่อนอื่นมาทำการกระทำจากนั้นคอนโทรลเลอร์ นี่เป็นสิ่งที่ค่อนข้างแปลก แต่ลักษณะของลายเซ็นนั้น

เพื่อชี้แจงสิ่งต่าง ๆ นี่เป็นเวอร์ชั่นที่ใช้งานได้ (ปรับตัวอย่างของโจเซฟ):

Html.ActionLink(article.Title, 
    "Login",  // <-- ActionMethod
    "Item",   // <-- Controller Name
    new { id = article.ArticleID }, // <-- Route arguments.
    null  // <-- htmlArguments .. which are none
    )

11

แล้วเรื่องนี้ล่ะ

<%=Html.ActionLink("Get Involved", 
                   "Show", 
                   "Home", 
                   new 
                       { 
                           id = "GetInvolved" 
                       }, 
                   new { 
                           @class = "menuitem", 
                           id = "menu_getinvolved" 
                       }
                   )%>

10
Html.ActionLink(article.Title, "Login/" + article.ArticleID, 'Item") 

สิ่งนี้ควรถูกทำเครื่องหมายเป็นคำตอบเนื่องจากมันเป็นสิ่งที่ผู้ถามคำถามกำลังมองหา ... อย่างไรก็ตามฉันจะทราบว่าคำตอบที่ทำเครื่องหมายไว้นั้นมีรายละเอียดที่ดีสำหรับผู้ใช้ในการตั้งค่าเส้นทางในรุ่นต่างๆอย่างถูกต้อง ของ MVC
Indy-Jones

9

หากคุณต้องการที่จะไปกางเกงแฟนซีทั้งหมดนี่คือวิธีที่คุณสามารถยืดมันให้สามารถทำสิ่งนี้ได้:

@(Html.ActionLink<ArticlesController>(x => x.Details(), article.Title, new { id = article.ArticleID }))

คุณจะต้องใส่สิ่งนี้ในSystem.Web.Mvcเนมสเปซ:

public static class MyProjectExtensions
{
    public static MvcHtmlString ActionLink<TController>(this HtmlHelper htmlHelper, Expression<Action<TController>> expression, string linkText)
    {
        var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection);

        var link = new TagBuilder("a");

        string actionName = ExpressionHelper.GetExpressionText(expression);
        string controllerName = typeof(TController).Name.Replace("Controller", "");

        link.MergeAttribute("href", urlHelper.Action(actionName, controllerName));
        link.SetInnerText(linkText);

        return new MvcHtmlString(link.ToString());
    }

    public static MvcHtmlString ActionLink<TController, TAction>(this HtmlHelper htmlHelper, Expression<Action<TController, TAction>> expression, string linkText, object routeValues)
    {
        var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection);

        var link = new TagBuilder("a");

        string actionName = ExpressionHelper.GetExpressionText(expression);
        string controllerName = typeof(TController).Name.Replace("Controller", "");

        link.MergeAttribute("href", urlHelper.Action(actionName, controllerName, routeValues));
        link.SetInnerText(linkText);

        return new MvcHtmlString(link.ToString());
    }

    public static MvcHtmlString ActionLink<TController>(this HtmlHelper htmlHelper, Expression<Action<TController>> expression, string linkText, object routeValues, object htmlAttributes) where TController : Controller
    {
        var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection);

        var attributes = AnonymousObjectToKeyValue(htmlAttributes);

        var link = new TagBuilder("a");

        string actionName = ExpressionHelper.GetExpressionText(expression);
        string controllerName = typeof(TController).Name.Replace("Controller", "");

        link.MergeAttribute("href", urlHelper.Action(actionName, controllerName, routeValues));
        link.MergeAttributes(attributes, true);
        link.SetInnerText(linkText);

        return new MvcHtmlString(link.ToString());
    }

    private static Dictionary<string, object> AnonymousObjectToKeyValue(object anonymousObject)
    {
        var dictionary = new Dictionary<string, object>();

        if (anonymousObject == null) return dictionary;

        foreach (PropertyDescriptor propertyDescriptor in TypeDescriptor.GetProperties(anonymousObject))
        {
            dictionary.Add(propertyDescriptor.Name, propertyDescriptor.GetValue(anonymousObject));
        }

        return dictionary;
    }
}

ซึ่งรวมถึงการแทนที่สองรายการRoute ValuesและHTML Attributesมุมมองทั้งหมดของคุณจะต้องเพิ่ม: @using YourProject.Controllersหรือคุณสามารถเพิ่มมุมมองของคุณweb.config <pages><namespaces>


1
ฉันประหลาดใจมากขึ้นอย่าใช้วิธีนี้ ดูเหมือนว่าเป็นอันตรายอย่างยิ่งที่จะใช้ตัวอักษรสตริงทั้งหมดในมุมมองของคุณเพื่อแสดงตัวควบคุม / การกระทำ
Johnathon Sullinger

มองหาสิ่งนี้มาตลอดชีวิตของฉัน
Worthy7

พยายามนี้ไม่ทำงาน ในตอนท้ายให้สตริงว่างเปล่า - ฉันคิดว่าเพราะฉันมีพารามิเตอร์ในการทำงานของฉัน
คุ้มค่า 7

คุณสามารถโพสต์ GitHub หรือที่อื่นด้วยรหัสนี้ได้ไหมเพื่อดูและดูว่าทำไมมันถึงไม่ทำงานสำหรับคุณ
Serj Sagan

2
ใช้คำว่า fancypants ได้ดี เราไม่เห็นว่าเพียงพอ
gdbj

7

ใช้พารามิเตอร์ที่กำหนดชื่อเพื่อให้สามารถอ่านได้และเพื่อหลีกเลี่ยงความสับสน

@Html.ActionLink(
            linkText: "Click Here",
            actionName: "Action",
            controllerName: "Home",
            routeValues: new { Identity = 2577 },
            htmlAttributes: null)

1

ด้วย MVC5 ฉันทำแบบนี้และมันเป็นรหัสการทำงาน 100% ....

@Html.ActionLink(department.Name, "Index", "Employee", new { 
                            departmentId = department.DepartmentID }, null)

พวกคุณสามารถรับแนวคิดจากสิ่งนี้ ...


0

ประเภทนี้ใช้:

@ Html.ActionLink ( "mainpage", "ดัชนี", "บ้าน")

MainPage: ชื่อของดัชนีข้อความ: Action View Home: HomeController

ฐานใช้ ActionLink

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>_Layout</title>
    <link href="@Url.Content("~/Content/bootsrap.min.css")" rel="stylesheet" type="text/css" />
</head>
<body>
    <div class="container">
        <div class="col-md-12">
            <button class="btn btn-default" type="submit">@Html.ActionLink("AnaSayfa","Index","Home")</button>
            <button class="btn btn-default" type="submit">@Html.ActionLink("Hakkımızda", "Hakkimizda", "Home")</button>
            <button class="btn btn-default" type="submit">@Html.ActionLink("Iletişim", "Iletisim", "Home")</button>
        </div> 
        @RenderBody()
        <div class="col-md-12" style="height:200px;background-image:url(/img/footer.jpg)">

        </div>
    </div>
</body>
</html>

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