ASP.NET Charting Control no longer working with .NET 4

后端 未结 3 1801
暗喜
暗喜 2021-01-12 20:19

I\'ve just upgraded to .NET 4 and my ASP.NET Chart Control no longer displays.

For .NET 3.5, the HTML produced by the control used to look like this:



        
相关标签:
3条回答
  • 2021-01-12 20:45

    We had this same problem on IIS 6 after upgrading from ASP.NET 3.5 to ASP.NET 4.0 with ASP.NET MVC. Everything was working fine on IIS 7, but IIS 6 gave us a problem.

    The problem was that the HttpContext.Current.Request.CurrentExecutionFilePath property gave a different result in IIS 6 and IIS 7:

    • Url: /Controller.mvc/Action/1/2
    • IIS 6: /Controller.mvc/Action/1/2
    • IIS 7: /Controller.mvc

    Which resulted in Urls for the charts like:

    • IIS 6: /Controller.mvc/Action/1/ChartImg.axd?i=chart_...
    • IIS 7: /ChartImg.axd?i=chart_...

    The ChartHttpHandler has got a function in there that calculates the path based 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?");
    }
    

    The way that the ASP.NET UrlRewriting was working, since the paths to ChartImg.axd still had .mvc in them, the MVC handler was getting invoked instead of the Chart handler.

    There were 3 ways we found to deal with it (see below for details):

    1. Add an explicit script map for ".mvc" to the ASP.NET 4.0 dll
    2. Add some additional ignore routes to the route table to cover permutations
    3. Override the Execute() of Controller and put in a redirect back to /ChartImg.axd

    (1) Turns out that if we added a script map for .mvc via IIS 6.0 for .mvc the Request.CurrentExecutionFilePath would get calculated as the root path how we wanted it instead of as the deeper path

    • IIS 6.0 Manager
    • Properties -> Home Directory -> Configuration
    • Mappings tab
    • Executable: c:\winnt\microsoft.net\framework\v4.0.30319\aspnet_isapi.dll, Extension: .mvc

    (2) We found that adding some route table entries would work, but we had to account for all depths possible in the paths to get ASP.NET MVC to ignore the ChartImg.axd if it were deeply embedded in the path and not at the root:

    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) By overriding the Execute() on all our controllers by making a base controller that all our controllers inherit from, we could globally override the Execute() to account for this situation and redirect to /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;
               }
           }
        }
    
    0 讨论(0)
  • 2021-01-12 20:45

    Thanks for your answers, but I don't think mine was an IIS6/IIS7 problem.

    I traced it to the fact that the default value for ImageStorageMode on a ChartControl has changed from UseImageLocation to UseHttpHandler. My ChartControl now has some extra attributes and all works fine.

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

    I had to also change the ImageLocation to be non-relative (by adding /Temp/) as that also caused a problem when iterating over the ChartControl's DataPoints in some code-behind.

    0 讨论(0)
  • 2021-01-12 21:04

    While @Michael's solution is informative on why this problem exists, there is a simpler solution. When registering the routes in your controllers handle in global.asax.cs, you could add an ignored route with a contstraint, as follows:

    protected void Application_Start() {
        ...
        RouteTable.Routes.Ignore("{*pathInfo}", new { pathInfo = @"^.*(ChartImg.axd)$" });
        ...
    }
    
    0 讨论(0)
提交回复
热议问题