¿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.

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

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

¿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("~/")

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/


26

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

System.Web.HttpRuntime.AppDomainAppVirtualPath

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.


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("~"))

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)

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("~/");
        }
}

+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.


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.


3

Puede usar el siguiente script a la vista:

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

3

Para ASP.NET MVC 4 es un poco diferente:

string url = HttpContext.Request.Url.AbsoluteUri;

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,"/" );

3

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

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

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

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


@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

Quizás sea una mejor solución.

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

utilizando

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

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

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");


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

0

Simplemente en una línea obtenga BaseUrl

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

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


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();
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.