代码之家  ›  专栏  ›  技术社区  ›  Oundless

ASP.NET图表控件不再与.NET 4一起使用

  •  6
  • Oundless  · 技术社区  · 16 年前

    我刚刚升级到.NET4,我的ASP.NET图表控件不再显示。

    对于.NET 3.5,控件生成的HTML通常如下所示:

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

    现在,对于.NET 4,它看起来是这样的(注意源路径中的更改):

    <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;" />
    

    图表位于MVC局部视图中,该视图位于MVC区域文件夹“Statistics”和MVC视图文件夹“Summary”(即“/Areas/Statistics/Views/Summary”)中,因此这显然是路径更改的来源。

    我所做的只是将System.Web.DataVisualization程序集从3.5切换到4.0。

    3 回复  |  直到 16 年前
        1
  •  18
  •   Kevin    16 年前

    虽然@Michael的解决方案提供了关于为什么存在这个问题的信息,但是有一个更简单的解决方案。在global.asax.cs中的控制器句柄中注册路由时,可以使用contstraint添加忽略的路由,如下所示:

    protected void Application_Start() {
        ...
        RouteTable.Routes.Ignore("{*pathInfo}", new { pathInfo = @"^.*(ChartImg.axd)$" });
        ...
    }
    
        2
  •  8
  •   Michael Ferrante    16 年前

    在使用ASP.NETMVC从ASP.NET3.5升级到ASP.NET4.0之后,我们在IIS6上遇到了同样的问题。在iis7上一切正常,但是iis6给了我们一个问题。

    问题是HttpContext.Current.Request.CurrentExecutionFilePath属性在IIS 6和IIS 7中给出了不同的结果:

    • 网址: /Controller.mvc/Action/1/2
    • /控制器.mvc/Action/1/2
    • IIS 7: /Controller.mvc

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

    ChartHttpHandler中有一个函数,它根据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?");
    }
    

    按照ASP.NET UrlRewriting的工作方式,由于ChartImg.axd的路径中仍然包含.mvc,因此调用的是mvc处理程序而不是图表处理程序。

    我们找到了3种处理方法(详见下文):

    1. 将“.mvc”的显式脚本映射添加到ASP.NET 4.0 dll
    2. 重写Controller的Execute(),并将重定向放回/ChartImg.axd

    (1) 结果表明,如果我们通过.mvc的IIS 6.0为.mvc添加一个脚本映射,那么Request.CurrentExecutionFilePath将被计算为我们想要的根路径,而不是更深的路径

    • 属性->主目录->配置
    • 映射选项卡
    • 可执行文件:c:\winnt\microsoft.net\framework\v4.0.30319\aspnet\u isapi.dll,扩展名:.mvc

    (2) 我们发现添加一些路由表条目是可行的,但是我们必须考虑路径中所有可能的深度,才能使ASP.NET MVC忽略ChartImg.axd(如果它深入嵌入路径而不是根目录):

    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) 通过在所有控制器上重写Execute(),使所有控制器都继承自一个基本控制器,我们可以全局重写Execute(),以说明这种情况,并重定向到/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;
               }
           }
        }
    
        3
  •  2
  •   Oundless    15 年前

    谢谢你的回答,但我不认为我的问题是IIS6/IIS7。

    我把它追溯到 ImageStorageMode ChartControl UseImageLocation UseHttpHandler . 我的 图表控件 现在有一些额外的属性,一切正常。

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

    我还得换衣服 ImageLocation 非相对的 /Temp/ 图表控件 DataPoints 在一些代码背后。