Tuvimos este mismo problema en IIS 6 después de actualizar de ASP.NET 3.5 a ASP.NET 4.0 con ASP.NET MVC. Todo funcionaba bien en IIS 7, pero IIS 6 nos dio un problema.
El problema era que la propiedad HttpContext.Current.Request.CurrentExecutionFilePath dio un resultado diferente en IIS 6 y IIS 7:
- Url:
/Controller.mvc/Action/1/2
- IIS 6:
/Controller.mvc/Action/1/2
- IIS 7:
/Controller.mvc
que dio lugar a las URL de los gráficos como:
- IIS 6:
/Controller.mvc/Action/1/ChartImg.axd?i=chart_...
- IIS 7:
/ChartImg.axd?i=chart_...
El ChartHttpHandler tiene una función en la que hay que calcula la ruta con sede fuera del HttpContext.Current.Request.CurrentExecutionFilePath:
private static string GetHandlerUrl()
{
string str = Path.GetDirectoryName(HttpContext.Current.Request.CurrentExecutionFilePath ?? "").Replace(@"\", "/");
if (!str.EndsWith("/", StringComparison.Ordinal))
{
str = str + "/";
}
return (str + "ChartImg.axd?");
}
La forma en que funcionaba la UrlRewriting de ASP.NET, ya que las rutas a ChartImg.axd todavía tenían .mvc en ellas, el manejador de MVC se invocaba en lugar del manejador de gráfico.
había 3 maneras que encontramos para tratar con él (ver más abajo para más detalles):
- Añadir un mapa de la escritura explícita para ".mvc" al ASP.NET 4.0 DLL
- Agregue un poco adicional ignorar rutas a la tabla de rutas para cubrir permutaciones
- anular el Ejecutar() del controlador y poner en una redirección de nuevo a /ChartImg.axd
(1) Resulta que si agregamos un mapa de script para .mvc a través de IIS 6.0 para .mvc, la Solicitud.CurrentExecutionFilePath conseguiría calculado como la ruta de raíz lo que queríamos en lugar de como el camino más profundo
- Administrador de IIS 6.0
- Propiedades -> Directorio Inicio -> Configuración
- Asignaciones pestaña
- ejecutable: C: \ WINNT \ microsoft.net \ Framework \ v4.0.30319 \ aspnet_isapi.dll, Extensión: .mvc
(2) Se encontró que el anuncio Algunas entradas de la tabla de rutas funcionarían, pero tuvimos que dar cuenta de todas las profundidades posibles en las rutas para que ASP.NET MVC ignorase el ChartImg.axd si estaba profundamente incrustado en la ruta y no en la raíz:
RouteTable.Routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
RouteTable.Routes.IgnoreRoute("{a}/{resource}.axd/{*pathInfo}");
RouteTable.Routes.IgnoreRoute("{a}/{b}/{resource}.axd/{*pathInfo}");
RouteTable.Routes.IgnoreRoute("{a}/{b}/{c}/{resource}.axd/{*pathInfo}");
RouteTable.Routes.IgnoreRoute("{a}/{b}/{c}/{d}/{resource}.axd/{*pathInfo}");
(3) reemplazando el Execute() en todos nuestros controladores haciendo un controlador de base que todos nuestros controladores heredan de, podríamos globalmente anular el Execute() para dar cuenta de esta situación y redirigir a/ChartImg. axd
public partial class MyController: Controller
{
protected override void Execute(RequestContext cc)
{
// the url for chartimg.axd to be in the application root. /Controller.mvc/Action/Param1/ChartImg.axd gets here first,
// but we want it to go to /ChartImg.axd, in which case the IgnoreRoute does work and the chart http handler does it's thing.
if (cc.HttpContext.Request.Url.AbsoluteUri.Contains("ChartImg.axd"))
{
var url = new UriBuilder(cc.HttpContext.Request.Url);
url.Path = "/ChartImg.axd";
cc.HttpContext.Response.Redirect(url.ToString());
return;
}
}
}
el RouteTable.Routes.IgnoreRoute adicional hizo el truco para nosotros. – badMonkey