ฉันจะค้นหา URL ที่แน่นอนของการกระทำใน ASP.NET MVC ได้อย่างไร


239

ฉันต้องทำสิ่งนี้:

<script type="text/javascript">
    token_url = "http://example.com/your_token_url";
</script>

ฉันกำลังใช้ MVC รุ่นเบต้า แต่ฉันไม่สามารถหาวิธีที่จะได้รับ url ที่สมบูรณ์ของการกระทำ ฉันต้องการทำสิ่งนี้:

<%= Url.AbsoluteAction("Action","Controller")) %>

มีตัวช่วยหรือวิธีหน้าสำหรับสิ่งนี้หรือไม่

คำตอบ:


480

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

Url.Action("Action", null, null, Request.Url.Scheme);

6
ที่น่าสนใจดังนั้นถ้าคุณระบุโปรโตคอล URL นั้นแน่นอน
Casebash

24
คำตอบนี้เป็นคำตอบที่ดีกว่าวิธีนี้ Resharper ยังคงสามารถตรวจสอบว่ามีการกระทำและตัวควบคุมอยู่ ฉันขอแนะนำให้ใช้ Request.Url.Scheme แทน http ซึ่งทั้ง http และ https ได้รับการสนับสนุน
Pbirkoff

2
@Pirkirkoff ยอมรับว่านี่เป็นคำตอบที่ดีที่สุด แต่คุณอาจต้องการทราบว่าคุณสามารถใส่คำอธิบายประกอบวิธีการของคุณเองเพื่อให้ ReSharper รู้ว่าพารามิเตอร์นั้นแสดงถึงการกระทำ / ตัวควบคุม ด้วยวิธีนี้ R # ยังคงสามารถตรวจสอบความถูกต้องของสตริงที่คุณให้ได้
Drew Noakes

3
การปรับปรุงเล็กน้อยอาจเป็นการแทนที่"http"ด้วยRequest.Url.Schemeดังนั้นหากคุณใช้ HTTPS URL ที่สร้างขึ้นจะใช้ HTTPS ด้วย
Erik Schierboom

1
วิธีนี้ใช้ได้ผลHtml.ActionLinkเช่นกัน (วิธีใด ๆ ที่ใช้โปรโตคอล 2 ตัวสุดท้ายใน MVC 4)
Chris

74

ขยาย UrlHelper

namespace System.Web.Mvc
{
    public static class HtmlExtensions
    {
        public static string AbsoluteAction(this UrlHelper url, string action, string controller)
        {
            Uri requestUrl = url.RequestContext.HttpContext.Request.Url;

            string absoluteAction = string.Format(
                "{0}://{1}{2}",
                requestUrl.Scheme,
                requestUrl.Authority,
                url.Action(action, controller));

            return absoluteAction;
        }
    }
}

จากนั้นเรียกมันว่าสิ่งนี้

<%= Url.AbsoluteAction("Dashboard", "Account")%>

แก้ไข - คำอธิบายประกอบ RESHARPER

ความคิดเห็นที่ถูกโหวตขึ้นมากที่สุดในคำตอบที่ยอมรับคือThis answer is the better one, this way Resharper can still validate that the Action and Controller exists.นี่คือตัวอย่างวิธีที่คุณจะได้รับพฤติกรรมแบบเดียวกัน

using JetBrains.Annotations

namespace System.Web.Mvc
{
    public static class HtmlExtensions
    {
        public static string AbsoluteAction(
            this UrlHelper url,
            [AspMvcAction]
            string action,
            [AspMvcController]
            string controller)
        {
            Uri requestUrl = url.RequestContext.HttpContext.Request.Url;

            string absoluteAction = string.Format(
                "{0}://{1}{2}",
                requestUrl.Scheme,
                requestUrl.Authority,
                url.Action(action, controller));

            return absoluteAction;
        }
    }
}

ข้อมูลสนับสนุน:


3
ฉันจะเพิ่มพารามิเตอร์ที่เป็นตัวเลือกสำหรับโซลูชันนี้ด้วย ควรครอบคลุมทุกกรณี
Eugeniu Torica

ดีมาก! ฉันใช้รหัสนี้ แต่ฉันสร้างอาร์กิวเมนต์ UU เพียงอย่างเดียวเพื่อให้ผู้เรียกสามารถสร้างมันโดยใช้วิธี Url ใดก็ได้ที่พวกเขาชอบ (ค่าเราเตอร์ ฯลฯ ) และวิธีการของคุณสามารถทำให้มันสัมพันธ์กันได้ ดังนั้นของฉันคือ: AbsoluteUrl (UrlHelper url นี้, สตริงญาติ UUU)
Rob Kent


21

ใช้คำตอบของ @Charlino เป็นแนวทางฉันมากับสิ่งนี้

เอกสาร ASP.NET MVC สำหรับ UrlHelperแสดงให้เห็นว่า Url.Action จะกลับ Url ที่มีคุณสมบัติครบถ้วนถ้าชื่อโฮสต์และโปรโตคอลจะถูกส่งผ่านใน. ฉันสร้างผู้ช่วยเหลือเหล่านี้จะบังคับให้ชื่อโฮสต์และโปรโตคอลที่จะให้ โหลดเกินจำนวนมากทำมิเรอร์โอเวอร์โหลดสำหรับ Url.Action:

using System.Web.Routing;

namespace System.Web.Mvc {
    public static class HtmlExtensions {

        public static string AbsoluteAction(this UrlHelper url, string actionName) {
            Uri requestUrl = url.RequestContext.HttpContext.Request.Url;
            return url.Action(actionName, null, (RouteValueDictionary)null, 
                              requestUrl.Scheme, null);
        }

        public static string AbsoluteAction(this UrlHelper url, string actionName, 
                                            object routeValues) {
            Uri requestUrl = url.RequestContext.HttpContext.Request.Url;
            return url.Action(actionName, null, new RouteValueDictionary(routeValues), 
                              requestUrl.Scheme, null);
        }

        public static string AbsoluteAction(this UrlHelper url, string actionName, 
                                            RouteValueDictionary routeValues) {
            Uri requestUrl = url.RequestContext.HttpContext.Request.Url;
            return url.Action(actionName, null, routeValues, requestUrl.Scheme, null);
        }

        public static string AbsoluteAction(this UrlHelper url, string actionName, 
                                            string controllerName) {
            Uri requestUrl = url.RequestContext.HttpContext.Request.Url;
            return url.Action(actionName, controllerName, (RouteValueDictionary)null, 
                              requestUrl.Scheme, null);
        }

        public static string AbsoluteAction(this UrlHelper url, string actionName, 
                                            string controllerName, 
                                            object routeValues) {
            Uri requestUrl = url.RequestContext.HttpContext.Request.Url;
            return url.Action(actionName, controllerName, 
                              new RouteValueDictionary(routeValues), requestUrl.Scheme, 
                              null);
        }

        public static string AbsoluteAction(this UrlHelper url, string actionName, 
                                            string controllerName, 
                                            RouteValueDictionary routeValues) {
            Uri requestUrl = url.RequestContext.HttpContext.Request.Url;
            return url.Action(actionName, controllerName, routeValues, requestUrl.Scheme, 
                              null);
        }

        public static string AbsoluteAction(this UrlHelper url, string actionName, 
                                            string controllerName, object routeValues, 
                                            string protocol) {
            Uri requestUrl = url.RequestContext.HttpContext.Request.Url;
            return url.Action(actionName, controllerName, 
                              new RouteValueDictionary(routeValues), protocol, null);
        }

    }
}

4
ขอบคุณสำหรับรหัสช่วยฉันได้มาก แต่ก็มีปัญหากับโซลูชันนี้ซึ่งมักเกิดขึ้นระหว่างการพัฒนา หากเว็บไซต์ที่โฮสต์บนพอร์ตเฉพาะข้อมูลของพอร์ตรวมอยู่ในrequestUrl.Authorityเช่นlocalhost: 4423 ด้วยเหตุผลบางอย่างวิธีการดำเนินการผนวกพอร์ตอีกครั้ง ดังนั้นอาจเป็นข้อผิดพลาดภายใน Action Method หรือคุณไม่ควรระบุพอร์ตที่นี่ แต่คุณสมบัติใดที่มีอยู่ในคำขอเป็นคุณสมบัติที่เหมาะสม (DnsSafeHost หรือโฮสต์) การแก้ปัญหาค่อนข้างง่าย: เพียงแค่ใส่ค่า nullและวิธีการดำเนินการจะเติมในค่าที่เหมาะสม
ntziolis

ฉันได้อัปเดตคำตอบเพื่อรวมคำแนะนำของ @ ntziolis แล้ว
Andrew Arnott

3

ฉันไม่แน่ใจว่ามีวิธีการทำอยู่หรือไม่ แต่คุณสามารถหมุนวิธี HtmlHelper ของคุณเองได้

บางสิ่งบางอย่างดังต่อไปนี้

namespace System.Web.Mvc
{
    public static class HtmlExtensions
    {
        public static string AbsoluteAction(this HtmlHelper html, string actionUrl)
        {
            Uri requestUrl = html.ViewContext.HttpContext.Request.Url;

            string absoluteAction = string.Format("{0}://{1}{2}",
                                                  requestUrl.Scheme,
                                                  requestUrl.Authority,
                                                  actionUrl);

            return absoluteAction;
        }
    }
}

จากนั้นเรียกมันว่าสิ่งนี้

<%= Html.AbsoluteAction(Url.Action("Dashboard", "Account"))%> »

HTHs ชาร์ลส์


2

คำตอบที่สมบูรณ์พร้อมอาร์กิวเมนต์จะเป็น:

var url = Url.Action("ActionName", "ControllerName", new { id = "arg_value" }, Request.Url.Scheme);

และนั่นจะสร้าง URL ที่แน่นอน


1

ผลลัพธ์เดียวกัน แต่สะอาดกว่าเล็กน้อย (ไม่มีการต่อสตริง / การจัดรูปแบบ):

public static Uri GetBaseUrl(this UrlHelper url)
{
    Uri contextUri = new Uri(url.RequestContext.HttpContext.Request.Url, url.RequestContext.HttpContext.Request.RawUrl);
    UriBuilder realmUri = new UriBuilder(contextUri) { Path = url.RequestContext.HttpContext.Request.ApplicationPath, Query = null, Fragment = null };
    return realmUri.Uri;
}

public static string ActionAbsolute(this UrlHelper url, string actionName, string controllerName)
{
    return new Uri(GetBaseUrl(url), url.Action(actionName, controllerName)).AbsoluteUri;
}

0

อาจจะ (?) นี้:

<%= 
  Request.Url.GetLeftPart(UriPartial.Authority) + 
  Url.Action("Action1", "Controller2", new {param1="bla", param2="blabla" })
%>

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