我刚刚升级到.NET 4,我的ASP.NET Chart Control不再显示。
对于.NET 3.5,控件生成的HTML看起来像这样:
<img id="20_Chart" src="/ChartImg.axd?i=chart_5f6a8fd179a246a5a0f4f44fcd7d5e03_0.png&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&g=16eb7881335e47dcba16fdfd8339ba1a" alt="" style="height:300px;width:300px;border-width:0px;" />
图表位于名为“Statistics”的MVC Area文件夹中的MVC局部视图和名为“Summary”的MVC Views文件夹(即“/ Areas / Statistics / Views / Summary”),所以这显然是路径的变化来自。
我所做的就是将System.Web.DataVisualization程序集从3.5切换到4.0。
非常感谢任何帮助。
答案 0 :(得分:18)
虽然@ Michael的解决方案可以提供有关此问题存在的信息,但有一个更简单的解决方案。在global.asax.cs中注册控制器句柄中的路由时,可以添加一个带有约束的忽略路由,如下所示:
protected void Application_Start() {
...
RouteTable.Routes.Ignore("{*pathInfo}", new { pathInfo = @"^.*(ChartImg.axd)$" });
...
}
答案 1 :(得分: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
/Controller.mvc/Action/1/2
/Controller.mvc
这导致了Urls的图表如下:
/Controller.mvc/Action/1/ChartImg.axd?i=chart_...
/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处理程序而不是Chart处理程序。
我们发现有3种方法可以处理它(详见下文):
(1)事实证明,如果我们通过IIS 6.0为.mvc添加了.mvc的脚本映射,那么Request.CurrentExecutionFilePath将被计算为我们想要的根路径而不是更深的路径
(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。 p>
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;
}
}
}
答案 2 :(得分:2)
感谢您的回答,但我认为我的问题不是IIS6 / IIS7。
我追溯到ImageStorageMode
上ChartControl
的默认值已从UseImageLocation
更改为UseHttpHandler
这一事实。我的ChartControl
现在有一些额外的属性,一切正常。
<asp:Chart ... ImageStorageMode="UseImageLocation" ImageLocation="/Temp/ChartPic_#SEQ(300,3)">
我还必须将ImageLocation
更改为非亲属(通过添加/Temp/
),因为在迭代ChartControl
DataPoints
时也会导致问题在一些代码隐藏中。