Gọi UrlHelper trong các mô hình trong ASP.NET MVC


159

Tôi cần tạo một số URL trong một mô hình trong ASP.NET MVC. Tôi muốn gọi một cái gì đó như UrlHelper.Action () sử dụng các tuyến đường để tạo URL. Tôi không ngại điền vào chỗ trống thông thường, như tên máy chủ, sơ đồ, v.v.

Có phương pháp nào tôi có thể gọi cho điều đó? Có cách nào để xây dựng một UrlHelper không?


1
Tôi đã suy nghĩ về điều này bản thân mình, nhưng hãy lưu ý rằng Url.Action sẽ tạo ra một URL tương đối. Hãy chắc chắn rằng đó là những gì bạn muốn.
Sông Vivian

Câu trả lời:


277

Mẹo hữu ích, trong bất kỳ ứng dụng ASP.NET nào, bạn có thể nhận được tài liệu tham khảo về HTTPContext hiện tại

HttpContext.Current

được lấy từ System.Web. Do đó, phần sau sẽ hoạt động ở mọi nơi trong ứng dụng ASP.NET MVC:

UrlHelper url = new UrlHelper(HttpContext.Current.Request.RequestContext);
url.Action("ContactUs"); // Will output the proper link according to routing info

Thí dụ:

public class MyModel
{
    public int ID { get; private set; }
    public string Link
    {
        get
        {
            UrlHelper url = new UrlHelper(HttpContext.Current.Request.RequestContext);
            return url.Action("ViewAction", "MyModelController", new { id = this.ID });
        }
    }

    public MyModel(int id)
    {
        this.ID = id;
    }
}

Gọi thuộc Linktính trên một đối tượng MyModel đã tạo sẽ trả về Url hợp lệ để xem Mô hình dựa trên định tuyến trong Global.asax


Bạn có chắc chắn có một HTTPContext.C hiện.Request.RequestContext không? HttpContext.Cản.Request dường như không có RequestContext.
Pupeno

1
Thật ki quặc. Tôi chỉ thử nghiệm giải pháp này và nó hoạt động hoàn hảo. Tôi đang chạy ASP.NET MVC 2 Preview 2, nhưng tôi nghĩ rằng nó hoạt động trên tất cả các phiên bản. Không chắc chắn tại sao nó không làm việc cho bạn. Bạn đang tạo lớp bên ngoài một dự án MVC? Ngoài ra, hãy đảm bảo có usingcả hai System.WebSystem.Web.Mvc
Omar

Tôi đang ở trong một dự án ASP.NET MVC 1, tôi đã nghĩ về việc thiếu các ứng dụng nhưng tôi có cả hai.
Pupeno

Không thực sự chắc chắn tại sao nó không hiển thị. Nếu bất cứ ai khác có thể xác nhận điều này không tồn tại trong ASP.NET MVC 1 thì thật tuyệt. Tôi chỉ có một máy có cài đặt VS2010 và MVC 2. Nếu bạn quan tâm, MVC RC 2 haacked.com/archive/2009/12/16/aspnetmvc-2-rc.aspx
Omar

6
Lưu ý rằng Request.RequestContex được hỗ trợ trong .NET4 +
h - n

64

Tôi thích câu trả lời của Omar nhưng điều đó không hiệu quả với tôi. Chỉ để ghi lại, đây là giải pháp tôi đang sử dụng:

var httpContext = HttpContext.Current;

if (httpContext == null) {
  var request = new HttpRequest("/", "http://example.com", "");
  var response = new HttpResponse(new StringWriter());
  httpContext = new HttpContext(request, response);
}

var httpContextBase = new HttpContextWrapper(httpContext);
var routeData = new RouteData();
var requestContext = new RequestContext(httpContextBase, routeData);

return new UrlHelper(requestContext);

Nó chứa URL của trang web của tôi. Ở đó, tôi loại bỏ nó.
Pupeno

4
Xem xét rằng lớp UrlHelper dựa trên bối cảnh yêu cầu (và bối cảnh HTTP), việc xây dựng các đối tượng bối cảnh đó theo cách thủ công có thể mang lại kết quả không mong muốn. Nếu httpContext.C hiện tại là null và bạn sử dụng phương pháp này, tôi sẽ tiến hành thận trọng.
Sean

4
Coi chừng câu trả lời này - RequestContext ngớ ngẩn dẫn đến một UrlHelper luôn trả về chuỗi rỗng.
gknicker

47

Một UrlHelper có thể được xây dựng từ bên trong một hành động của Bộ điều khiển với các điều sau:

 var url = new UrlHelper(this.ControllerContext.RequestContext);
 url.Action(...);

Bên ngoài bộ điều khiển, UrlHelper có thể được xây dựng bằng cách tạo RequestContext từ RouteTable.Routes RouteData.

HttpContextWrapper httpContextWrapper = new HttpContextWrapper(System.Web.HttpContext.Current);
UrlHelper urlHelper = new UrlHelper(new RequestContext(httpContextWrapper, RouteTable.Routes.GetRouteData(httpContextWrapper)));

(Dựa trên câu trả lời của Brian, với một chỉnh sửa mã nhỏ được thêm vào.)


2
Nhưng tôi không có bộ điều khiển trong mô hình.
Pupeno

Được rồi tôi xin lỗi, tôi không chắc chính xác nơi mã được thực thi. Hãy để tôi xem ...
Nathan Taylor

2
Không cần tạo bối cảnh yêu cầu mới:var urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);
bradlis7

Đẹp @ bradlis7. Đó có phải là MVC 5 không?
Nathan Taylor

1
Không hoạt động, bởi vì this.ControllerContext.RequestContextlà một HttpRequestContext, và nhà xây dựng của UrlHelpermong đợi a RequestContext. Cả hai lớp không liên quan.
Mùa đông mùa đông

8

Vâng, bạn có thể khởi tạo nó. Bạn có thể làm một cái gì đó như:

var ctx = new HttpContextWrapper(HttpContext.Current);
UrlHelper helper = new UrlHelper(
   new RequestContext(ctx,
   RouteTable.Routes.GetRouteData(ctx));

RouteTable.Routeslà một thuộc tính tĩnh, vì vậy bạn sẽ ổn ở đó; để có được một HttpContextBasetài liệu tham khảo, HttpContextWrappertham khảo HttpContextHttpContextcung cấp đó.


Điều này sẽ không hoạt động, mặc dù nó rất gần. Xem câu trả lời của tôi dưới đây.
Nathan Taylor

3

Sau khi thử tất cả các câu trả lời khác, tôi đã kết thúc với

$"/api/Things/Action/{id}"

Kẻ ghét sẽ ghét ¯ \ _ (ツ) _ / ¯


0

Tôi đã cố gắng làm một cái gì đó tương tự từ trong một trang (bên ngoài bộ điều khiển).

UrlHelper không cho phép tôi xây dựng nó dễ dàng như câu trả lời của Pottaos, nhưng sau đó tôi nhớ một mẹo cũ để thực hiện điều tương tự:

string ResolveUrl(string pathWithTilde)

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.