Làm cách nào để tìm url tuyệt đối của một hành động trong ASP.NET MVC?


239

Tôi cần phải làm một cái gì đó như thế này:

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

Tôi đang sử dụng phiên bản Beta của MVC, nhưng tôi không thể tìm ra cách lấy url tuyệt đối của một hành động. Tôi muốn làm một cái gì đó như thế này:

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

Có một phương pháp trợ giúp hoặc Trang cho việc này?

Câu trả lời:


480

Bấm vào đây để biết thêm thông tin, nhưng về cơ bản không cần phương thức mở rộng. Nó đã được nướng sẵn, chỉ là không theo một cách rất trực quan.

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

6
Thật thú vị, vì vậy nếu bạn chỉ định giao thức, URL là tuyệt đối
Casebash

24
Câu trả lời này là câu trả lời tốt hơn, theo cách này, Resharper vẫn có thể xác thực rằng Hành động và Trình điều khiển tồn tại. Tôi sẽ đề nghị sử dụng Request.Url.Scheme thay vì http, theo cách đó cả http và https đều được hỗ trợ.
Pbirkoff

2
@Pbirkoff, đồng ý rằng đây là câu trả lời tốt nhất nhưng bạn có thể muốn biết rằng bạn có thể chú thích các phương thức của riêng mình cho ReSharper để biết rằng các tham số thể hiện hành động / bộ điều khiển. Theo cách đó, R # vẫn có thể xác nhận các chuỗi bạn cung cấp, vì nó rất tốt.
Drew Noakes

3
Một cải tiến nhỏ có thể là để thay thế "http" với Request.Url.Schemedo đó nếu bạn sử dụng HTTPS url tạo cũng sẽ sử dụng HTTPS.
Erik Schierboom

1
Điều này cũng hoạt động Html.ActionLinktốt (bất kỳ phương thức nào có giao thức, ví dụ 2 trong MVC 4)
Chris

74

Mở rộng 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;
        }
    }
}

Sau đó gọi nó như thế này

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

EDIT - THÔNG BÁO GIẢI QUYẾT

Nhận xét được đánh giá cao nhất về câu trả lời được chấp nhận là This answer is the better one, this way Resharper can still validate that the Action and Controller exists.Vì vậy, đây là một ví dụ về cách bạn có thể có hành vi tương tự.

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;
        }
    }
}

Thông tin hỗ trợ:


3
Tôi cũng sẽ thêm các tham số tùy chọn cho giải pháp này. Điều này sẽ bao gồm tất cả các trường hợp.
Eugeniu Torica

Rất đẹp! Tôi đã sử dụng mã này nhưng tôi đã tạo đối số tương đối duy nhất để người gọi có thể tạo nó bằng bất kỳ phương thức Url nào họ thích (giá trị bộ định tuyến, v.v.) và phương thức của bạn có thể chịu trách nhiệm làm cho nó tương đối. Vì vậy, của tôi là: AbsoluteUrl (url UrlHelper này, chuỗi tương đốiUrl).
Rob Kent

26
<%= Url.Action("About", "Home", null, Request.Url.Scheme) %>
<%= Url.RouteUrl("Default", new { Action = "About" }, Request.Url.Scheme) %>

21

Sử dụng câu trả lời của @Charlino làm hướng dẫn, tôi đã nghĩ ra điều này.

Các tài liệu ASP.NET MVC cho UrlHelper cho thấy Url.Action sẽ trả về một Url đầy đủ điều kiện nếu một hostname và giao thức được thông qua vào. Tôi tạo ra những người giúp đỡ để buộc các hostname và giao thức được cung cấp. Nhiều quá tải phản ánh tình trạng quá tải cho 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
Thx cho mã, đã giúp tôi rất nhiều, nhưng có một vấn đề với giải pháp này thường xuất hiện trong quá trình phát triển. Nếu trang web được lưu trữ trên một cổng cụ thể, thông tin cổng được bao gồm trong requestUrl.Authority , như localhost: 4423 . Vì một số lý do, phương thức Action nối lại cổng. Vì vậy, đây là một lỗi bên trong Phương thức hành động hoặc bạn không được phép cung cấp cổng ở đây. Nhưng thuộc tính có sẵn nào trong yêu cầu là đúng (DnsSafehost hoặc Host)? Vâng, giải pháp khá đơn giản: Chỉ cần cung cấp null và phương thức Action sẽ điền đúng giá trị.
ntziolis

Tôi đã cập nhật câu trả lời để kết hợp đề xuất của @ ntziolis.
Andrew Arnott

3

Tôi không chắc chắn nếu có một cách được xây dựng để làm điều đó, nhưng bạn có thể cuộn phương thức HtmlHelper của riêng bạn.

Một cái gì đó như sau

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;
        }
    }
}

Sau đó gọi nó như thế này

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

HTHs, Charles


2

Câu trả lời đầy đủ với các đối số sẽ là:

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

và điều đó sẽ tạo ra một url tuyệt đối


1

Kết quả tương tự nhưng sạch hơn một chút (không nối / định dạng chuỗi):

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

Có lẽ điều này (?):

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

0

env: phiên bản lõi dotnet 1.0.4

Url.Action("Join",null, null,Context.Request.IsHttps?"https":"http");
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.