Mieliśmy ten sam problem na IIS 6 po aktualizacji z ASP.NET 3.5 do ASP.NET 4.0 z ASP.NET MVC. Wszystko działało dobrze na IIS 7, ale IIS 6 dał nam problem.
Problem polegał na tym, że właściwość HttpContext.Current.Request.CurrentExecutionFilePath dała inny wynik IIS 6 i 7: IIS
- URL:
/Controller.mvc/Action/1/2
- IIS 6:
/Controller.mvc/Action/1/2
- IIS 7:
/Controller.mvc
co spowodowało adresy URL przebojów jak:
- IIS 6:
/Controller.mvc/Action/1/ChartImg.axd?i=chart_...
- IIS 7:
/ChartImg.axd?i=chart_...
ChartHttpHandler ma funkcję tam, który oblicza trasy na podstawie poza 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?");
}
Sposób działania funkcji UrlRewriting programu ASP.NET, ponieważ ścieżki do pliku ChartImg.axd nadal zawierały .mvc, procedura obsługi MVC została wywołana zamiast programu obsługi wykresu.
Były 3 sposoby, które znaleźliśmy do czynienia z nim (szczegóły poniżej):
- Dodaj wyraźny skryptu mapę dla „.mvc” do 4,0 dll ASP.NET
- Dodaj pewne dodatkowe ignorować trasy do tablicy tras w celu pokrycia permutacji
- zmieniane niezależnie od Wykonanie (i) sterownika i umieścić w przekierowanie do /ChartImg.axd
(1) Okazuje się, że jeśli dodaliśmy mapę skryptu dla .mvc za pośrednictwem IIS 6.0 dla .mvc żądania.CurrentExecutionFilePath dostanie obliczony jako ścieżka korzenia, jak chcieliśmy, a nie jako głębszą ścieżką
- IIS 6.0 Menedżer
- Właściwości -> Home Directory -> Konfiguracja
- Mappings zakładka
- wykonywalnych: C: \ winnt \ microsoft.net \ framework \ v4.0.30319 \ aspnet_isapi.dll, rozszerzenie: .mvc
(2) Okazało się, że reklama niektóre pozycje tabeli routingu działałyby, ale musieliśmy uwzględnić wszystkie możliwe głębokości na ścieżkach, aby ASP.NET MVC zignorował wykres ChartImg.axd, jeśli był głęboko osadzony w ścieżce, a nie w katalogu głównym:
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) nadrzędnymi Execute() na wszystkich naszych kontrolerów poprzez kontroler bazowej że wszystkie nasze kontrolery dziedziczą od mogliśmy globalnie przesłonić Execute(), aby wyjaśnić tę sytuację i przekierować do/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;
}
}
}
dodatkowe RouteTable.Routes.IgnoreRoute załatwiło sprawę za nas. – badMonkey