¿Cómo puedo obtener la URL base de mi aplicación web en ASP.NET MVC?

300

¿Cómo puedo determinar rápidamente cuál es la URL raíz para mi aplicación ASP.NET MVC? Es decir, si IIS está configurado para servir mi aplicación en http://example.com/foo/bar , entonces me gustaría poder obtener esa URL de manera confiable que no implique obtener la URL actual del solicitar y cortarlo de una manera frágil que se rompe si cambio la ruta de mi acción.

La razón por la que necesito la URL base es que esta aplicación web llama a otra que necesita la raíz de la aplicación web de la persona que llama para fines de devolución de llamada.

Benjamin Pollack
fuente

Respuestas:

399

Suponiendo que tiene un objeto Solicitud disponible, puede usar:

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

Si no está disponible, puede acceder a él a través del contexto:

var request = HttpContext.Current.Request
tghw
fuente
8
¿Qué es urlHelper.Content("~")? ¿Cómo creo definir urlHelper? ¡Gracias!
Maxim Zaslavsky
31
@Maxim, puede sustituir probablemente el
UpTheCreek
13
Lo que terminé 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
77
Para MVC 4 usoControllerContext.RequestContext.HttpContext.Request
fila1
77
@Url.Content("~")resuelve "/", que no es la url base.
Andrew Hoffman
114

Así que ninguno de los enumerados aquí funcionó para mí, pero usando algunas de las respuestas, obtuve algo que funciona:

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

Actualización para ASP.NET Core / MVC 6:

ASP.NET Corehace que este proceso sea un poco más doloroso, especialmente si eres profundo en tu código. Tienes 2 opciones para llegar alHttpContext

1) Pásalo desde tu controller:

var model = new MyClass(HttpContext);

luego en model:

private HttpContext currentContext;

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

2) Quizás la forma más limpia es inyectarlo en su clase, que comienza con el registro de los tipos en su Startup:

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

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

entonces haz que te lo inyecten así:

private HttpContext currentContext;

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

en cualquier caso, aquí está la actualización 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}";
}
Serj Sagan
fuente
¿Dónde pusiste este método?
Josh Dean
3
Eso realmente depende de la frecuencia con la que necesite usarlo ... si se trata de un acuerdo de uso único, simplemente colóquelo en la clase donde necesita estos datos, si anticipa usarlo en varias clases en su aplicación, entonces uso un carpeta llamada Helpersen la base de mi aplicación, tengo una staticclase llamada Staticsy pongo funciones como la anterior allí ... solo asegúrese de cambiar la anterior de public string GetBaseUrl()apublic static string GetBaseUrl()
Serj Sagan
Como actualización, ya no uso una clase llamada Statics, sino que la dividí en usos más específicos, por lo que en este caso esto entraría en mi UrlHelperclase
Serj Sagan
1
De todas las opciones que he encontrado, esta es la única que realmente funcionó para mí. Tu # 2 que es. ¡Gracias un montón!
adeldegan
2
Elegí esto porque es el único que menciona PathBase, que es exactamente lo que necesitaba. ¡Gracias!
Dave
69

En codigo:

Url.Content("~/");

MVC3 Razor Sintaxis:

@Url.Content("~/")
mxasim
fuente
11
Esto está bien para usar en las páginas de Razor, pero si está intentando pasar la URL a una fuente externa, no le dará la URL completa.
krillgar
55
No funciona Simplemente agregará en /lugar del nombre real.
Mrchief
2
¿Dónde está Code el Urlasistente disponible para usted de inmediato? Quizás solo en el Controller. Ciertamente, no en el ViewModelo cualquier otro lugar classdonde pueda necesitar esto ..
Serj Sagan
43

Tal vez sea una extensión o modificación de las respuestas publicadas aquí, pero uso simplemente la siguiente línea y funciona:

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

Cuando mi camino es: http://host/iis_foldername/controller/action
entonces recibo:http://host/iis_foldername/

Bronek
fuente
26

El siguiente fragmento me funciona muy bien en MVC4, y no necesita un HttpContextdisponible:

System.Web.HttpRuntime.AppDomainAppVirtualPath
usuario666142
fuente
Parece funcionar en MVC3 también. Lo uso jQuery.load()para construir la URL del controlador y la acción que quiero llamar: $('#myplaceholder').load('@(Html.Raw(HttpRuntime.AppDomainAppVirtualPath))/MyController/MyAction', ...);
Kjell Rilbe
¿Por qué harías eso? en lugar de llamar a Url.Action?
BlackTigerX
44
No funciona cuando se implementa en Azure. Las respuestas mejor calificadas funcionan en este escenario.
Jeff Dunlop
25

El truco para confiar en IIS es que los enlaces de IIS pueden ser diferentes de sus URL públicas (WCF lo estoy mirando a usted), especialmente con máquinas de producción multi-homed. Tiendo a vectorizar hacia el uso de la configuración para definir explícitamente la url "base" para fines externos, ya que tiende a ser un poco más exitosa que extraerla del objeto Request.

Wyatt Barnett
fuente
2
También es cierto para servidores detrás de equilibradores de carga o proxies.
Ismael
20

Para una URL base absoluta, use esto. Funciona con HTTP y HTTPS.

new Uri(Request.Url, Url.Content("~"))
arni
fuente
15

Esta es una conversión de una propiedad asp.net a MVC . Es un método de url de raíz que canta y baila.

Declarar una clase 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 desde un controlador:

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

Para usar en una vista:

@using MyTestProject.Helpers

PathHelper.FullyQualifiedApplicationPath(Request)
Paul Zahra
fuente
1
Esta es la única respuesta que explica la posibilidad de que un sitio se ejecute en un puerto que no sea 80. Todas las otras respuestas son inseguras en lo que a mí respecta. ¡Gracias!
jebar8
12

En MVC _Layout.cshtml:

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

¡Eso es lo 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("~/");
        }
}
katibaer
fuente
+1 por usar <base>. También puede omitir el Esquema para que funcione con http o https. Eso significa que puede comenzar la url con //.
Jess
5

Esto funciona bien para mí (también con un equilibrador de carga):

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

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

Especialmente si está utilizando números de puerto no estándar, el uso de Request.Url.Authority aparece como un buen lead al principio, pero falla en un entorno LB.

Tadej Gregorcic
fuente
3

Podría tener un método estático que examine HttpContext.Current y decida qué URL usar (servidor de desarrollo o en vivo) según la ID del host. HttpContext podría incluso ofrecer una forma más fácil de hacerlo, pero esta es la primera opción que encontré y funciona bien.

Adrian Grigore
fuente
3

Puede usar el siguiente script a la vista:

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

Para ASP.NET MVC 4 es un poco diferente:

string url = HttpContext.Request.Url.AbsoluteUri;
Fernando Vezzali
fuente
3

Esto está funcionando en ASP .NET MVC 4. En cualquier acción del controlador puede escribir: 1stline obtiene toda la url + Cadena de consulta. La segunda línea elimina la ruta local y la consulta, el último símbolo '/'. La tercera línea agrega el símbolo '/' en la última posición.

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

en html simple y ASP.NET o ASP.NET MVC si está usando la etiqueta:

<a href="~/#about">About us</a>
Ravi Anand
fuente
3

Para url con alias de aplicación como http://example.com/appAlias/ ... Puedes probar esto:

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

En la página web en sí:

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

En el javascript:

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

Esto funciona para mi proyecto MVC, espero que ayude

Andrew Day
fuente
@hemp ¿Lo editó pero no votó por él? Espero que los puntos sean valiosos para usted
Andrew Day
Esta pregunta y las respuestas asociadas no fueron útiles para mi problema en particular, así que no intenté ni voté por ninguna de ellas. Edité este porque lo vi y pensé que podría ser una respuesta decente si estaba formateado correctamente. Solo trato de ser un buen ciudadano.
cáñamo
Además, no se ganan puntos de reputación por editar una respuesta.
cáñamo
2

Puse esto en la cabeza de mi _Layout.cshtml

 <base href="~/" />
mal funcionamiento del cineam
fuente
2

Quizás sea una mejor solución.

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

utilizando

<a href="@baseUrl" class="link">Base URL</a>
em
fuente
1
No lo probé, pero dudo que esto funcione cuando la url base es virtual directamente. es decir. localhost / myApp
emragins
1

Para MVC 4:

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

Lo siguiente funcionó sólidamente para mí

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");
venu
fuente
1

Esta fue mi solución (usando .net core 3.1, en un controlador api):

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

Simplemente en una línea obtenga BaseUrl

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

//output example: https://stackoverflow.com
Zahid Tanveer
fuente
0

agregue esta función en clase estática en proyecto como clase de utilidad:

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

usa este código en cualquier lugar y disfrútalo:

var baseUrl = Utility.GetBaseUrl();
DLMAN
fuente