Criando uma URL no Controlador .NET MVC

131

Eu preciso ser capaz de construir um link na Ação no controlador para enviar um email. Qual é a melhor prática para fazer isso? Eu não quero construí-lo sozinho, caso minhas rotas mudem.

Devo ter uma visão para cada email, renderizá-lo e enviá-lo? Essa pode ser uma boa maneira de fazê-lo.

ScottBelchak
fonte

Respostas:

230

Se você apenas deseja obter o caminho para uma determinada ação, use UrlHelper:

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

se você deseja criar um hiperlink:

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

O Intellisense fornecerá o significado de cada um dos parâmetros.


Atualização dos comentários : o controlador já possui UrlHelper:

string url = this.Url.Action("About", "Home", null); 
Gidon
fonte
17
Acompanhamento: Para o penúltimo parâmetro (o RouteValueDictionary), aqui está um exemplo: new System.Web.Routing.RouteValueDictionary (new {id = 1})
Matthew M.
15
Você não precisa construir um novo UrlHelper; existe uma propriedade .Url no controlador que fornecerá uma com o RequestContext correto.
Tobias J
De onde vem a "raiz"? Se eu precisar codificar o nome da rota que estou tentando corresponder, por que não codificar apenas o URL?
Xr280xr
@ xr280xr: Eu acredito neste exemplo "Root" é o nome da rota, conforme definido no método RegisterRoutes (geralmente no RouteConfig). Para mim, era "Padrão" (como era quando eu criei meu projeto).
Andy
3
Você não precisa atualizar um UrlHelper, basta acessar a propriedade Url na classe Controller.
Jay Douglass
22

Se você precisar do URL completo (por exemplo, para enviar por email), considere usar um dos seguintes métodos internos:

Com isso, você cria a rota a ser usada para criar o URL:

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

Aqui, o URL é criado após o mecanismo de rota determinar o correto:

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

Nos dois métodos, os 2 últimos parâmetros especificam o protocolo e o nome do host.

Saudações.

andresfiuba
fonte
7
FYI usando Url.Action(action, controller, routevalue, protocol)também produz URL completo, assim você não precisa especificar o nome do host se não precisar.
Endy Tjahjono
1
Estou recebendo o seguinte URL com o número da porta dobrado. Como faço para corrigir isso, por favor? http: // localhost: 54383: 54383 / MyArea / MyController / Details / 1
Patee Gutee
12

Eu tive o mesmo problema e parece que a resposta de Gidon tem uma pequena falha: gera uma URL relativa, que não pode ser enviada por correio.

Minha solução é assim:

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

Dessa maneira, uma URL completa é gerada e funciona mesmo que o aplicativo esteja em vários níveis no servidor de hospedagem e use uma porta diferente de 80.

EDIT: Eu achei isso útil também.

Moshe
fonte
Observe que isso tem uma grande vulnerabilidade de segurança. Basta que alguém modifique o cabeçalho da solicitação para conter uma URL mal-intencionada como host e seu aplicativo enviaria um email oficial contendo um link para um site perigoso.
V0ldek 02/04/19
7

Outra maneira de criar um URL absoluto para uma ação:

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

var absoluteUrl = new System.Uri(currentUrl, relativeUrl);
Sphinxxx
fonte
4

Sei que essa é uma pergunta antiga, mas, caso você esteja tentando fazer a mesma coisa no ASP.NET Core, veja como você pode criar o UrlHelper dentro de uma ação:

var urlHelper = new UrlHelper(this.ControllerContext);

Ou, você pode apenas usar a Controller.Urlpropriedade se herdar Controller.

Darren
fonte