ASP.NET Charting Control不再使用.NET 4

Oun*_*ess 6 asp.net asp.net-mvc charts .net-4.0

我刚刚升级到.NET 4,我的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;" />
Run Code Online (Sandbox Code Playgroud)

现在,对于.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;" />
Run Code Online (Sandbox Code Playgroud)

该图表位于MVC局部视图中,该文件夹位于名为"Statistics"的MVC Area文件夹和名为"Summary"的MVC Views文件夹中(即"/ Areas/Statistics/Views/Summary"),因此这显然是改变路径来自.

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

任何帮助非常感谢.

Kev*_*vin 18

虽然@ Michael的解决方案可以提供有关此问题存在的原因,但有一个更简单的解决方案.当注册在控制器路由中的global.asax.cs处理,你可以添加一个contstraint忽略的路径,如下所示:

protected void Application_Start() {
    ...
    RouteTable.Routes.Ignore("{*pathInfo}", new { pathInfo = @"^.*(ChartImg.axd)$" });
    ...
}
Run Code Online (Sandbox Code Playgroud)


Mic*_*nte 8

在使用ASP.NET MVC从ASP.NET 3.5升级到ASP.NET 4.0之后,我们在IIS 6上遇到了同样的问题.在IIS 7上一切正常,但IIS 6给我们带来了一个问题.

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

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

这导致了Urls的图表如下:

  • 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?");
}
Run Code Online (Sandbox Code Playgroud)

ASP.NET UrlRewriting的工作方式,因为ChartImg.axd的路径仍然包含.mvc,MVC处理程序被调用而不是Chart处理程序.

我们发现有3种方法可以处理它(详见下文):

  1. 将".mvc"的显式脚本映射添加到ASP.NET 4.0 dll
  2. 在路由表中添加一些额外的忽略路由以覆盖排列
  3. 覆盖Controller的Execute()并将重定向放回/ChartImg.axd

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

  • IIS 6.0管理器
  • 属性 - >主目录 - >配置
  • 映射选项卡
  • 可执行文件:c:\ winnt\microsoft.net\framework\v4.0.30319\aspnet_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}");
Run Code Online (Sandbox Code Playgroud)

(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;
           }
       }
    }
Run Code Online (Sandbox Code Playgroud)


Oun*_*ess 3

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

我追踪到ImageStorageModea的默认值ChartControl已从 更改UseImageLocationUseHttpHandler。我的ChartControl现在有一些额外的属性并且一切正常。

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

我还必须将 更改ImageLocation为非相对的(通过添加),因为这在某些隐藏代码中迭代/Temp/时也会导致问题。ChartControlDataPoints