Como posso obter o URL base do meu aplicativo da web no ASP.NET MVC?


300

Como posso determinar rapidamente qual é o URL raiz do meu aplicativo ASP.NET MVC? Ou seja, se o IIS estiver configurado para atender meu aplicativo em http://example.com/foo/bar , eu gostaria de obter esse URL de uma maneira confiável, que não envolva a obtenção do URL atual do solicitar e desmembrá-lo de alguma maneira frágil que quebre se eu redirecionar minha ação.

O motivo pelo qual eu preciso da URL base é que esse aplicativo Web chama outro que precisa da raiz do aplicativo Web chamador para fins de retorno de chamada.

Respostas:


399

Supondo que você tenha um objeto Request disponível, você pode usar:

string.Format("{0}://{1}{2}", Request.Url.Scheme, Request.Url.Authority, Url.Content("~"));

Se não estiver disponível, você poderá acessá-lo através do contexto:

var request = HttpContext.Current.Request

8
O que é urlHelper.Content("~")? Como crio define urlHelper? Obrigado!
Maxim Zaslavsky

31
@ Maxim, você provavelmente pode substituir Url.Content ("~")
UpTheCreek

13
O que eu acabei usando:var request = HttpContext.Current.Request; urlBase = string.Format("{0}://{1}{2}", request.Url.Scheme, request.Url.Authority, (new System.Web.Mvc.UrlHelper(request.RequestContext)).Content("~"));
Peter

7
Para MVC 4 eu usoControllerContext.RequestContext.HttpContext.Request
row1

7
@Url.Content("~")resolve para "/", que não é o URL base.
Andrew Hoffman

114

Portanto, nenhum dos listados aqui funcionou para mim, mas usando algumas das respostas, obtive algo funcionando:

public string GetBaseUrl()
{
    var request = HttpContext.Current.Request;
    var appUrl = HttpRuntime.AppDomainAppVirtualPath;

    if (appUrl != "/") 
        appUrl = "/" + appUrl;

    var baseUrl = string.Format("{0}://{1}{2}", request.Url.Scheme, request.Url.Authority, appUrl);

    return baseUrl;
}

Atualização para o ASP.NET Core / MVC 6:

ASP.NET Coretorna esse processo um pouco mais doloroso, especialmente se você está profundamente envolvido no seu código. Você tem 2 opções para chegar aoHttpContext

1) Passe do seu controller:

var model = new MyClass(HttpContext);

então em model:

private HttpContext currentContext;

public MyClass(HttpContext currentContext)
{
    this.currentContext = currentContext;
}

2) Talvez a maneira mais limpa seja injetá-lo na sua turma, que começa com o registro dos tipos no seu Startup:

public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services.AddMvc();

    services.AddTransient<MyClass, MyClass>();
    services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}

injete-o assim:

private HttpContext currentContext;

public MyClass(IHttpContextAccessor httpContextAccessor)
{
    currentContext = httpContextAccessor.HttpContext;
}

nos dois casos, eis a atualização para .NET Core GetBaseUrl():

public string GetBaseUrl()
{
    var request = currentContext.Request;

    var host = request.Host.ToUriComponent();

    var pathBase = request.PathBase.ToUriComponent();

    return $"{request.Scheme}://{host}{pathBase}";
}

Onde você colocou esse método?
Josh Dean #

3
Isso realmente depende da frequência com que você precisa usá-lo ... se esse é um acordo de uso único, basta colocá-lo na classe em que você precisa desses dados, se você antecipar usá-lo em várias classes no seu aplicativo, então eu uso um pasta chamada Helpersna base do meu aplicativo, eu tenho uma staticclasse chamada Staticse coloco funções como as anteriores lá ... apenas certifique-se de alterar as public string GetBaseUrl()public static string GetBaseUrl()
opções

Como uma atualização, eu já não usar uma classe chamada Statics, em vez eu tê-lo separado em mais usos específicos, por isso, neste caso, isso seria ir para a minha UrlHelperclasse
Serj Sagan

1
De todas as opções que encontrei, essa é a única que realmente funcionou para mim. Seu # 2 que é. Muitíssimo obrigado!
adeldegan

2
Promovido isso porque é o único a mencionar o PathBase, que é exatamente o que eu precisava. Obrigado!
31419 Dave

69

Em código:

Url.Content("~/");

Sintaxe do MVC3 Razor:

@Url.Content("~/")

11
Isso é bom para usar nas páginas do Razor, mas se você estiver tentando passar o URL para uma fonte externa, ele não fornecerá o URL completo.
precisa saber é o seguinte

5
Isso não funciona. Apenas adicionará em /vez do nome real.
Mrchief

2
Onde o Code está Urldisponível para o ajudante logo de cara? Talvez apenas no Controller. Certamente não no ViewModelou qualquer outro classonde você pode precisar isso ..
Serj Sagan

43

Talvez seja extensão ou modificação das respostas postadas aqui, mas eu uso simplesmente a seguinte linha e funciona:

Request.Url.GetLeftPart(UriPartial.Authority) + Url.Content("~")

Quando meu caminho é: http://host/iis_foldername/controller/action
então eu recebo:http://host/iis_foldername/


26

O seguinte snippet funciona muito bem para mim no MVC4 e não precisa de um HttpContextdisponível:

System.Web.HttpRuntime.AppDomainAppVirtualPath

Parece funcionar também no MVC3. Eu uso-o jQuery.load()para construir a URL para o controlador e a ação que desejo chamar: $('#myplaceholder').load('@(Html.Raw(HttpRuntime.AppDomainAppVirtualPath))/MyController/MyAction', ...);
Kjell Rilbe 19/10/12

Por que você faria isso? em vez de chamar Url.Action?
BlackTigerX

4
Não funciona quando implantado no Azure. Respostas com classificação mais alta funcionam nesse cenário.
Jeff Dunlop

25

O truque para confiar no IIS é que as ligações do IIS podem ser diferentes dos seus URLs públicos (WCF, estou olhando para você), especialmente com máquinas de produção com hospedagem múltipla. Eu costumo usar vetor de configuração para definir explicitamente o URL "base" para fins externos, pois isso tende a ser um pouco mais bem-sucedido do que extraí-lo do objeto Request.


2
Isso também se aplica aos servidores que utilizam balanceadores de carga ou proxies.
Ishmaeel

20

Para um URL base absoluto, use isso. Funciona com HTTP e HTTPS.

new Uri(Request.Url, Url.Content("~"))

15

Esta é uma conversão de uma propriedade asp.net para MVC . É um método praticamente todo de cantar e dançar.

Declare uma classe auxiliar:

namespace MyTestProject.Helpers
{
    using System.Web;

    public static class PathHelper
    {
        public static string FullyQualifiedApplicationPath(HttpRequestBase httpRequestBase)
        {
            string appPath = string.Empty;

            if (httpRequestBase != null)
            {
                //Formatting the fully qualified website url/name
                appPath = string.Format("{0}://{1}{2}{3}",
                            httpRequestBase.Url.Scheme,
                            httpRequestBase.Url.Host,
                            httpRequestBase.Url.Port == 80 ? string.Empty : ":" + httpRequestBase.Url.Port,
                            httpRequestBase.ApplicationPath);
            }

            if (!appPath.EndsWith("/"))
            {
                appPath += "/";
            }

            return appPath;
        }
    }
}

Uso:

Para usar de um controlador:

PathHelper.FullyQualifiedApplicationPath(ControllerContext.RequestContext.HttpContext.Request)

Para usar em uma exibição:

@using MyTestProject.Helpers

PathHelper.FullyQualifiedApplicationPath(Request)

1
Essa é a única resposta que explica a possibilidade de um site ser executado em uma porta que não seja 80. Todas as outras respostas são inseguras para mim. Obrigado!
jebar8

12

No MVC _Layout.cshtml:

<base href="@Request.GetBaseUrl()" />

É isso que usamos!

public static class ExtensionMethods
{
public static string GetBaseUrl(this HttpRequestBase request)
        {
          if (request.Url == (Uri) null)
            return string.Empty;
          else
            return request.Url.Scheme + "://" + request.Url.Authority + VirtualPathUtility.ToAbsolute("~/");
        }
}

+1 para usar <base>. Além disso, você pode omitir o esquema para que ele funcione com http ou https. Isso significa que você pode iniciar o URL //.
Jess

5

Isso funciona bem para mim (também com um balanceador de carga):

@{
    var urlHelper = new UrlHelper(Html.ViewContext.RequestContext);
    var baseurl = urlHelper.Content(“~”);
}

<script>
    var base_url = "@baseurl";
</script>

Especialmente se você estiver usando números de porta não padrão, usar Request.Url.Authority parecerá um bom lead no início, mas falhará em um ambiente LB.


3

Você pode ter um método estático que analise HttpContext.Current e decida qual URL usar (servidor de desenvolvimento ou ativo), dependendo do ID do host. O HttpContext pode até oferecer uma maneira mais fácil de fazer isso, mas esta é a primeira opção que encontrei e funciona bem.


3

Você pode usar o seguinte script na exibição:

<script type="text/javascript">
    var BASE_URL = '<%= ResolveUrl("~/") %>';
</script>

3

Para o ASP.NET MVC 4, é um pouco diferente:

string url = HttpContext.Request.Url.AbsoluteUri;

3

Isso está funcionando no ASP .NET MVC 4 Em qualquer ação do controlador, você pode escrever: 1stline obtém o URL inteiro + Query String. 2a linha remover caminho local e consulta, último símbolo '/'. Terceira linha, adicione o símbolo '/' na última posição.

Uri url = System.Web.HttpContext.Current.Request.Url;
string UrlLink = url.OriginalString.Replace(url.PathAndQuery,"");
UrlLink = String.Concat(UrlLink,"/" );

3

em html simples e ASP.NET ou ASP.NET MVC, se você estiver usando a tag:

<a href="~/#about">About us</a>

3

Para URLs com alias de aplicação como http://example.com/appAlias/ ... Você pode tentar o seguinte:

var req = HttpContext.Current.Request;
string baseUrl = string.Format("{0}://{1}/{2}", req.Url.Scheme, req.Url.Authority, req.ApplicationPath);

3

Na própria página da web:

<input type="hidden" id="basePath" value="@string.Format("{0}://{1}{2}",
  HttpContext.Current.Request.Url.Scheme,
  HttpContext.Current.Request.Url.Authority,
  Url.Content("~"))" />

No javascript:

function getReportFormGeneratorPath() {
  var formPath = $('#reportForm').attr('action');
  var newPath = $("#basePath").val() + formPath;
  return newPath;
}

Isso funciona para o meu projeto MVC, espero que ajude


@hemp Editou, mas não votou nele? Espero que os pontos são importantes para você
Andrew Dia

Esta pergunta e as respostas associadas não foram úteis para o meu problema específico, por isso não tentei ou votei em nenhum deles. Editei este porque o vi e achei que poderia ser uma resposta decente se fosse formatado corretamente. Apenas tentando ser um bom cidadão.
cânhamo

Além disso, não há pontos de reputação ganhos para editar uma resposta.
cânhamo


2

Talvez seja uma solução melhor.

@{
   var baseUrl = @Request.Host("/");
}

usando

<a href="@baseUrl" class="link">Base URL</a>

1
Não testei, mas duvido que isso funcione quando o URL base for um virtual diretamente. ie localhost / myApp
emragins

1

Para MVC 4:

String.Format("{0}://{1}{2}", Url.Request.RequestUri.Scheme, Url.Request.RequestUri.Authority, ControllerContext.Configuration.VirtualPathRoot);

1

O seguinte funcionou solidamente para mim

var request = HttpContext.Request;
                        var appUrl = System.Web.HttpRuntime.AppDomainAppVirtualPath;

                        if (appUrl != "/")
                            appUrl = "/" + appUrl + "/";

                        var newUrl = string.Format("{0}://{1}{2}{3}/{4}", request.Url.Scheme, request.UrlReferrer.Host, appUrl, "Controller", "Action");


1

Esta foi a minha solução (usando o .net core 3.1, em um controlador api):

string baseUrl = $"{Request.Scheme}://{Request.Headers.Where(h => h.Key == "Host").First().Value}";

0

Simplesmente em uma linha, obtenha o BaseUrl

string baseUrl = new Uri(Request.Url, Url.Content("~")).AbsoluteUri;

//output example: https://stackoverflow.com


0

adicione esta função na classe estática no projeto como classe de utilitário:

conteúdo utility.cs :

public static class Utility
{
    public static string GetBaseUrl()
    {
        var request = HttpContext.Current.Request;
        var urlHelper = new UrlHelper(request.RequestContext);
        var baseUrl = $"{request.Url.Scheme}://{request.Url.Authority}{urlHelper.Content("~")}";
        return baseUrl;
    }
}

use este código em qualquer lugar e divirta-se:

var baseUrl = Utility.GetBaseUrl();
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.