Chúng tôi đã có cùng một vấn đề này trên IIS 6 sau khi nâng cấp từ ASP.NET 3.5 lên ASP.NET 4.0 với ASP.NET MVC. Tất cả mọi thứ đã được làm việc tốt trên IIS 7, nhưng IIS 6 đã cho chúng tôi một vấn đề.
Vấn đề là tài sản HttpContext.Current.Request.CurrentExecutionFilePath đã đưa ra một kết quả khác nhau trong IIS 6 và IIS 7:
- Url:
/Controller.mvc/Action/1/2
- IIS 6:
/Controller.mvc/Action/1/2
- IIS 7:
/Controller.mvc
Điều này dẫn đến Url cho các biểu đồ như:
- IIS 6:
/Controller.mvc/Action/1/ChartImg.axd?i=chart_...
- IIS 7:
/ChartImg.axd?i=chart_...
Các ChartHttpHandler đã có một chức năng trong đó cho phép tính con đường dựa off the 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?");
}
Cách mà ASP.NET UrlRewriting đang hoạt động, vì các đường dẫn đến ChartImg.axd vẫn có .mvc trong đó, trình xử lý MVC đã được gọi thay vì trình xử lý Chart.
Có 3 cách chúng tôi thấy để đối phó với nó (xem dưới đây để biết chi tiết):
- Thêm một bản đồ rõ ràng kịch bản cho ".mvc" đến 4,0 dll ASP.NET
- Thêm một số thêm bỏ qua các tuyến đường vào bảng định tuyến để trang trải hoán vị
- Override Execute() của bộ điều khiển và đặt trong một chuyển hướng trở lại /ChartImg.axd
(1) Chỉ ra rằng nếu chúng ta thêm một bản đồ kịch bản cho .mvc thông qua IIS 6.0 cho .mvc Yêu cầu.CurrentExecutionFilePath sẽ được tính bằng cách lấy đường dẫn gốc như thế nào chúng tôi muốn nó thay vì như con đường sâu hơn
- IIS 6.0 Quản lý
- Properties -> Home Directory -> Cấu hình
- Mappings tab
- Executable: c: \ winnt \ microsoft.net \ framework \ v4.0.30319 \ aspnet_isapi.dll, mở rộng: .mvc
(2) Chúng tôi nhận thấy rằng quảng cáo ding một số mục bảng tuyến đường sẽ làm việc, nhưng chúng tôi đã phải tính toán cho tất cả các độ sâu có thể trong các đường dẫn để có được ASP.NET MVC bỏ qua ChartImg.axd nếu nó được nhúng sâu trong đường dẫn và không phải ở gốc:
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) Bằng cách ghi đè Execute() trên tất cả các bộ điều khiển bằng cách tạo bộ điều khiển cơ sở mà tất cả các bộ điều khiển của chúng tôi kế thừa, chúng tôi có thể ghi đè lên Execute() trên toàn cầu và chuyển hướng đến/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;
}
}
}
bổ sung RouteTable.Routes.IgnoreRoute đã thực hiện thủ thuật cho chúng tôi. – badMonkey