สร้าง URL ในตัวช่วย HTML


168

โดยปกติในมุมมอง ASP.NET หนึ่งสามารถใช้ฟังก์ชั่นต่อไปนี้เพื่อรับ URL (ไม่ใช่<a>):

Url.Action("Action", "Controller");

อย่างไรก็ตามฉันไม่สามารถหาวิธีทำได้จากตัวช่วย HTML ที่กำหนดเอง ฉันมี

public class MyCustomHelper
{
   public static string ExtensionMethod(this HtmlHelper helper)
   {
   }
}

ตัวแปรตัวช่วยมีเมธอด Action และ GenerateLink แต่สร้างขึ้น<a>มา ฉันทำการขุดในซอร์สโค้ด ASP.NET MVC แต่ฉันไม่สามารถหาวิธีที่ตรงไปตรงมา

ปัญหาคือ Url ด้านบนเป็นสมาชิกของคลาสมุมมองและสำหรับอินสแตนซ์ของมันต้องการบริบทบางอย่างและแผนที่เส้นทาง (ซึ่งฉันไม่ต้องการที่จะจัดการกับและฉันไม่ควรจะอยู่แล้ว) หรืออีกทางหนึ่งอินสแตนซ์ของคลาส HtmlHelper ก็มีบริบทบางอย่างที่ฉันถือว่าเป็นส่วนหนึ่งของชุดย่อยของข้อมูลบริบทของอินสแตนซ์ Url (แต่ฉันไม่ต้องการจัดการกับมันอีก)

โดยสรุปฉันคิดว่ามันเป็นไปได้ แต่เนื่องจากฉันเห็นทุกอย่างเกี่ยวข้องกับการจัดการบางอย่างกับสิ่ง ASP.NET ภายในบางอย่างมากขึ้นฉันสงสัยว่ามีวิธีที่ดีกว่านี้หรือไม่

แก้ไข:ตัวอย่างเช่นความเป็นไปได้หนึ่งอย่างที่ฉันเห็นคือ:

public class MyCustomHelper
{
    public static string ExtensionMethod(this HtmlHelper helper)
    {
        UrlHelper urlHelper = new UrlHelper(helper.ViewContext.RequestContext);
        urlHelper.Action("Action", "Controller");
    }
}

แต่มันดูไม่ถูกต้อง ฉันไม่ต้องการที่จะจัดการกับอินสแตนซ์ของ UrlHelper ด้วยตัวเอง จะต้องมีวิธีที่ง่ายกว่า


3
ฉันรู้ว่านี่เป็นตัวอย่างที่ง่าย แต่สำหรับตัวอย่างที่แสดงฉันจะขยาย UrlHelper แทน HtmlHelper แม้ว่ารหัสจริงของคุณอาจจำเป็นต้องใช้ทั้งคู่
เครก Stuntz

ขออภัยฉันควรจะชัดเจนมากขึ้น: ฉันต้องการที่จะแสดง HTML ในวิธีการขยายและฉันต้องการที่จะสร้าง URL ของมัน
Jan Zich

คำตอบ:


217

คุณสามารถสร้าง url helper เช่นนี้ได้ภายในวิธีการขยาย html helper:

var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext);
var url = urlHelper.Action("Home", "Index")

2
ฉันคิดว่ามันจะดีกว่าถ้านวกรรมิกเริ่มต้น RouteCollection ด้วยnew UrlHelper(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection)
kpull1

22

คุณยังสามารถรับลิงก์โดยใช้UrlHelperคลาสสาธารณะและสแตติก:

UrlHelper.GenerateUrl(null, actionName, controllerName, null, null, null, routeValues, htmlHelper.RouteCollection, htmlHelper.ViewContext.RequestContext, true)

ในตัวอย่างนี้คุณไม่จำเป็นต้องสร้างคลาส UrlHelper ใหม่ซึ่งอาจเป็นประโยชน์เล็กน้อย


ฉันชอบคำตอบนี้มากขึ้นเพราะตั้งค่า RouteCollection
kpull1

10

นี่คือวิธีการต่อของฉันเล็ก ๆ สำหรับการเดินทางUrlHelperของHtmlHelperเช่น:

  public static partial class UrlHelperExtensions
    {
        /// <summary>
        /// Gets UrlHelper for the HtmlHelper.
        /// </summary>
        /// <param name="htmlHelper">The HTML helper.</param>
        /// <returns></returns>
        public static UrlHelper UrlHelper(this HtmlHelper htmlHelper)
        {
            if (htmlHelper.ViewContext.Controller is Controller)
                return ((Controller)htmlHelper.ViewContext.Controller).Url;

            const string itemKey = "HtmlHelper_UrlHelper";

            if (htmlHelper.ViewContext.HttpContext.Items[itemKey] == null)
                htmlHelper.ViewContext.HttpContext.Items[itemKey] = new UrlHelper(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection);

            return (UrlHelper)htmlHelper.ViewContext.HttpContext.Items[itemKey];
        }
    }

ใช้เป็น:

public static MvcHtmlString RenderManagePrintLink(this HtmlHelper helper, )
{    
    var url = htmlHelper.UrlHelper().RouteUrl('routeName');
    //...
}

(ฉันโพสต์ ans นี้สำหรับการอ้างอิงเท่านั้น)


วิธีการที่ยอดเยี่ยมเพราะมันจะนำวัตถุที่มีอยู่กลับมาใช้ใหม่แทนที่จะสร้างวัตถุใหม่
Mike

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