Panggil UrlHelper dalam model di ASP.NET MVC

159

Saya perlu membuat beberapa URL dalam model di ASP.NET MVC. Saya ingin memanggil sesuatu seperti UrlHelper.Action () yang menggunakan rute untuk menghasilkan URL. Saya tidak keberatan mengisi kekosongan yang biasa, seperti nama host, skema dan sebagainya.

Apakah ada metode yang bisa saya panggil untuk itu? Apakah ada cara untuk membangun UrlHelper?

pupeno
sumber
1
Saya sedang memikirkan hal ini sendiri, tetapi perlu diketahui bahwa Url.Action akan menghasilkan URL relatif. Pastikan itu yang Anda inginkan.
Sungai Vivian

Jawaban:

277

Kiat bermanfaat, dalam aplikasi ASP.NET apa pun, Anda bisa mendapatkan referensi dari HttpContext saat ini

HttpContext.Current

yang berasal dari System.Web. Oleh karena itu, berikut ini akan berfungsi di mana saja dalam aplikasi ASP.NET MVC:

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

Contoh:

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

Memanggil Linkproperti pada objek MyModel yang dibuat akan mengembalikan Url yang valid untuk melihat Model berdasarkan perutean di Global.asax

Omar
sumber
Apakah Anda yakin ada HttpContext.Current.Request.RequestContext? HttpContext.Current.Request tampaknya tidak memiliki RequestContext.
pupeno
1
Itu aneh. Saya baru saja menguji solusi ini dan berfungsi dengan baik. Saya menjalankan ASP.NET MVC 2 Pratinjau 2, tapi saya pikir ini berfungsi di semua versi. Tidak yakin mengapa itu tidak berhasil untuk Anda. Apakah Anda membuat kelas di luar proyek MVC? Juga pastikan ada usinguntuk keduanya System.WebdanSystem.Web.Mvc
Omar
Saya sedang mengerjakan proyek ASP.NET MVC 1, saya berpikir untuk melewatkan usings tetapi saya memiliki keduanya.
pupeno
Tidak begitu yakin mengapa itu tidak muncul. Jika ada orang lain yang bisa mengkonfirmasi ini tidak ada di ASP.NET MVC 1 itu akan bagus. Saya hanya memiliki satu mesin dengan VS2010 dan MVC 2 diinstal. Jika Anda tertarik, MVC RC 2 haacked.com/archive/2009/12/16/aspnetmvc-2-rc.aspx
Omar
6
Perhatikan bahwa Request.RequestContex didukung dalam .NET4 +
h - n
64

Saya suka jawaban Omar tapi itu tidak berhasil untuk saya. Sebagai catatan, ini adalah solusi yang saya gunakan sekarang:

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);
pupeno
sumber
Ini berisi URL situs saya. Di sana, saya menghapusnya.
pupeno
4
Menimbang bahwa kelas UrlHelper bergantung pada konteks permintaan (dan konteks HTTP), membuat objek konteks tersebut secara manual dapat menghasilkan hasil yang tidak terduga. Jika HttpContext.Current adalah nol dan Anda menggunakan pendekatan ini, saya akan melanjutkan dengan hati-hati.
Sean
4
Waspadai jawaban ini - RequestContext dummied menghasilkan UrlHelper yang selalu mengembalikan string kosong.
gknicker
47

UrlHelper dapat dibangun dari dalam aksi Pengendali dengan berikut ini:

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

Di luar pengontrol, UrlHelper dapat dibangun dengan membuat RequestContext dari RouteTable. Rute RouteData.

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

(Berdasarkan jawaban Brian, dengan koreksi kode minor ditambahkan.)

Nathan Taylor
sumber
2
Tapi saya tidak punya controller dalam model.
pupeno
Oke saya minta maaf, saya tidak yakin persis di mana kode itu dieksekusi. Biarkan saya memeriksanya ...
Nathan Taylor
2
Tidak perlu membuat konteks permintaan baru:var urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);
bradlis7
Nice @ bradlis7. Apakah itu MVC 5?
Nathan Taylor
1
Tidak berfungsi, karena this.ControllerContext.RequestContexta HttpRequestContext, dan konstruktor UrlHelpermengharapkan a RequestContext. Kedua kelas tidak berhubungan.
Florian Winter
8

Ya, Anda bisa instantiate. Anda dapat melakukan sesuatu seperti:

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

RouteTable.Routesadalah properti statis, jadi Anda harus OK di sana; untuk mendapatkan HttpContextBasereferensi, HttpContextWrappermengambil referensi ke HttpContext, dan HttpContextmengirimkannya.

Brian Mains
sumber
Ini tidak akan berhasil, meskipun sangat dekat. Lihat jawaban saya di bawah ini.
Nathan Taylor
3

Setelah mencoba semua jawaban lain, saya berakhir dengan

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

Pembenci akan membenci ¯ \ _ (ツ) _ / ¯

Musim Dingin Florian
sumber
0

Saya mencoba melakukan sesuatu yang serupa dari dalam halaman (di luar controller).

UrlHelper tidak mengizinkan saya membangunnya semudah jawaban Pablos, tapi kemudian saya ingat trik lama untuk efektif melakukan hal yang sama:

string ResolveUrl(string pathWithTilde)
vGazard
sumber
-30

Saya pikir yang Anda cari adalah ini:

Url.Action("ActionName", "ControllerName");
pengguna246874
sumber