2010-04-13 28 views
6

Tôi vừa nâng cấp lên .NET 4 và điều khiển biểu đồ ASP.NET của tôi không còn hiển thị nữa.Kiểm soát biểu đồ ASP.NET không còn hoạt động với .NET 4

Đối với .NET 3.5, HTML được tạo ra bởi sự kiểm soát sử dụng để trông như thế này:

<img id="20_Chart" src="/ChartImg.axd?i=chart_5f6a8fd179a246a5a0f4f44fcd7d5e03_0.png&amp;g=16eb7881335e47dcba16fdfd8339ba1a" alt="" style="height:300px;width:300px;border-width:0px;" /> 

và bây giờ, cho NET 4, nó trông như thế này (lưu ý sự thay đổi trong đường dẫn nguồn):

<img id="20_Chart" src="/Statistics/Summary/ChartImg.axd?i=chart_5f6a8fd179a246a5a0f4f44fcd7d5e03_0.png&amp;g=16eb7881335e47dcba16fdfd8339ba1a" alt="" style="height:300px;width:300px;border-width:0px;" /> 

Biểu đồ là trong một lần xem một phần MVC đó là trong một thư mục MVC Diện tích gọi là "Thống kê" và một MVC xem một folder tên là "Tóm tắt" (tức là "/ Khu vực/Thống kê/Views/Tóm tắt"), do đó điều này rõ ràng là nơi mà sự thay đổi của con đường đến từ đó.

Tất cả những gì tôi đã làm là chuyển đổi hội nghị System.Web.DataVisualization từ, 3.5 sang 4.0.

Bất kỳ trợ giúp nào được đánh giá cao.

Trả lời

1

Cám ơn câu trả lời của bạn, nhưng tôi không nghĩ rằng tôi là một IIS6/IIS7 vấn đề.

Tôi đã truy tìm thực tế là giá trị mặc định cho ImageStorageMode trên ChartControl đã thay đổi từ UseImageLocation thành UseHttpHandler. My ChartControl hiện có một số thuộc tính phụ và tất cả đều hoạt động tốt.

<asp:Chart ... ImageStorageMode="UseImageLocation" ImageLocation="/Temp/ChartPic_#SEQ(300,3)"> 

tôi cũng đã thay đổi ImageLocation là phi tương đối (bằng cách thêm /Temp/) như đó cũng gây ra một vấn đề khi iterating trên ChartControl 's DataPoints trong một số code-behind.

7

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

  1. Thêm một bản đồ rõ ràng kịch bản cho ".mvc" đến 4,0 dll ASP.NET
  2. 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ị
  3. 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; 
      } 
     } 
    } 
+1

bổ sung RouteTable.Routes.IgnoreRoute đã thực hiện thủ thuật cho chúng tôi. – badMonkey

18

Trong khi giải pháp @ Michael là thông tin về lý do tại sao là vấn đề tồn tại, có một giải pháp đơn giản hơn. Khi đăng ký các tuyến đường trong các bộ điều khiển của bạn xử lý trong global.asax.cs, bạn có thể thêm một tuyến đường bị bỏ qua với một contstraint, như sau:

protected void Application_Start() { 
    ... 
    RouteTable.Routes.Ignore("{*pathInfo}", new { pathInfo = @"^.*(ChartImg.axd)$" }); 
    ... 
} 
+1

Câu trả lời của Michael Ferrante thật tuyệt vời - nhưng tôi không thể bỏ phiếu đủ cho giải pháp này ... chúc mừng Kevin –

Các vấn đề liên quan