Tworzenie adresu URL w kontrolerze .NET MVC

133

Muszę być w stanie utworzyć łącze w akcji na kontrolerze, aby wysłać wiadomość e-mail. Jaka jest najlepsza praktyka, aby to zrobić? Nie chcę go konstruować samodzielnie na wypadek zmiany trasy.

Czy powinienem mieć widok dla każdego e-maila, renderować go i wysyłać? To może być dobry sposób na zrobienie tego.

ScottBelchak
źródło

Odpowiedzi:

235

Jeśli chcesz tylko uzyskać ścieżkę do określonej akcji, użyj UrlHelper:

UrlHelper u = new UrlHelper(this.ControllerContext.RequestContext);
string url = u.Action("About", "Home", null);

jeśli chcesz utworzyć hiperłącze:

string link = HtmlHelper.GenerateLink(this.ControllerContext.RequestContext, System.Web.Routing.RouteTable.Routes, "My link", "Root", "About", "Home", null, null);

Intellisense poda znaczenie każdego z parametrów.


Aktualizacja z komentarzy : kontroler ma już UrlHelper:

string url = this.Url.Action("About", "Home", null); 
Gideon
źródło
17
Kontynuacja: dla przedostatniego parametru (RouteValueDictionary) jest tutaj przykład: new System.Web.Routing.RouteValueDictionary (new {id = 1})
Matthew M.
16
Nie musisz tworzyć nowego UrlHelpera; na kontrolerze znajduje się właściwość .Url, która da ci właściwość z poprawnym RequestContext.
Tobias J
Skąd się bierze „Root”? Jeśli muszę zakodować na stałe nazwę trasy, którą próbuję dopasować, dlaczego nie zakodować na stałe adresu URL?
xr280xr
@ xr280xr: Wierzę, że w tym przykładzie „Root” to nazwa trasy zdefiniowana w metodzie RegisterRoutes (zwykle w RouteConfig). Dla mnie był to „Default” (tak jak wtedy, gdy tworzyłem projekt).
Andy
3
Nie musisz tworzyć nowego UrlHelpera, po prostu uzyskaj dostęp do właściwości Url w klasie Controller.
Jay Douglass,
23

Jeśli potrzebujesz pełnego adresu URL (na przykład do wysłania pocztą elektroniczną), rozważ użycie jednej z następujących wbudowanych metod:

W ten sposób utworzysz trasę, która zostanie użyta do zbudowania adresu URL:

Url.RouteUrl("OpinionByCompany", new RouteValueDictionary(new{cid=newop.CompanyID,oid=newop.ID}), HttpContext.Request.Url.Scheme, HttpContext.Request.Url.Authority)

Tutaj adres URL jest tworzony po tym, jak silnik tras określi właściwy:

Url.Action("Detail","Opinion",new RouteValueDictionary(new{cid=newop.CompanyID,oid=newop.ID}),HttpContext.Request.Url.Scheme, HttpContext.Request.Url.Authority)

W obu metodach ostatnie 2 parametry określają protokół i nazwę hosta.

Pozdrowienia.

andresfiuba
źródło
7
FYI using Url.Action(action, controller, routevalue, protocol)generuje również pełny adres URL, więc nie musisz określać nazwy hosta, jeśli nie musisz.
Endy Tjahjono
1
Otrzymuję następujący adres URL z podwojonym numerem portu. Jak mam to naprawić? http: // localhost: 54383: 54383 / MyArea / MyController / Details / 1
Patee Gutee
12

Miałem ten sam problem i wygląda na to, że odpowiedź Gidona ma jedną drobną wadę: generuje względny adres URL, którego nie można wysłać pocztą.

Moje rozwiązanie wygląda następująco:

string link = HttpContext.Request.Url.Scheme + "://" + HttpContext.Request.Url.Authority + Url.Action("ResetPassword", "Account", new { key = randomString });

W ten sposób generowany jest pełny adres URL, który działa nawet wtedy, gdy aplikacja znajduje się na serwerze hostingowym na kilku poziomach i używa portu innego niż 80.

EDIT: Znalazłem ten przydatny również.

Mosze
źródło
Należy pamiętać, że ma to poważną lukę w zabezpieczeniach. Wystarczy, że ktoś zmodyfikuje nagłówek żądania, aby zawierał złośliwy adres URL, a Twoja aplikacja wyśle ​​oficjalną wiadomość e-mail zawierającą odsyłacz do niebezpiecznej witryny.
V0ldek
8

Inny sposób na utworzenie bezwzględnego adresu URL do akcji:

var relativeUrl = Url.Action("MyAction");  //..or one of the other .Action() overloads
var currentUrl = Request.Url;

var absoluteUrl = new System.Uri(currentUrl, relativeUrl);
Sphinxxx
źródło
4

Wiem, że to stare pytanie, ale na wypadek, gdybyś próbował zrobić to samo w ASP.NET Core, oto jak możesz utworzyć UrlHelper wewnątrz akcji:

var urlHelper = new UrlHelper(this.ControllerContext);

Lub możesz po prostu użyć tej Controller.Urlwłaściwości, jeśli dziedziczysz z Controller.

Darren
źródło