After reading Delian Tchoparinov’s blog post (http://blogs.msdn.com/deliant/archive/2008/12/02/managing-chart-generated-images-with-chart-image-handler.aspx) on chart http handlers, I’ve spent some time attempting to get a custom IChartStorageHandler implementation functional. There isn’t a lot of documentation, but it seems like it should be fairly easily �and perfect for my needs. I’m using the chart control in a web farm and would like to use our existing cache solution to store the temporarily generated images.
Unfortunately, I am unable to get the handler parameter of the ChartImageHandler AppSetting to function as expected; an exception is thrown: Could not load type 'ChartHandlers.FileStorageHandler' from assembly 'System.Web.DataVisualization, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'.
According to Delian’s blog post, a handler [is] A custom IChartStorageHandler implementation. The value should be formatted as a fully qualified assembly name. For example: MyNamespace.MyClass.MyHandler. It’s not clear to me why it’s attempting to load my handler implementation out of the System.Web.DataVisualization assembly.
I’ve attempted a number of variations of the code below, but here’s the easiest setup:
1) In the chart sample solution, add a new file, “FileStorageHandler.cs� code is below. It simply implements the IChartStorageHandler interface. (I've also attempted putting this file into it's own dll, and referencing that dll in the ChartSamples Project)
using System;
using System.Web.UI.DataVisualization.Charting;
namespace ChartHandlers
{
public class FileStorageHandler : IChartStorageHandler
{
public void Delete(string key) { throw new NotImplementedException();}
public bool Exists(string key) { throw new NotImplementedException();}
public byte[] Load(string key) { throw new NotImplementedException();}
public void Save(string key, byte[] data) { throw new NotImplementedException();}
}
}
2) Edit the web.config to reference the handler. Replace the existing ChartImageHandler AppSetting with the following:
<appSettings>
<add key="ChartImageHandler" value="handler=ChartHandlers.FileStorageHandler" />
</appSettings>
3) Run the sample, and attempt to load any chart, an exception is thrown:
Server Error in '/WebSamples' Application.
--------------------------------------------------------------------------------
Could not load type 'ChartHandlers.FileStorageHandler' from assembly 'System.Web.DataVisualization, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.TypeLoadException: Could not load type 'ChartHandlers.FileStorageHandler' from assembly 'System.Web.DataVisualization, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[TypeLoadException: Could not load type 'ChartHandlers.FileStorageHandler' from assembly 'System.Web.DataVisualization, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'.]
System.RuntimeTypeHandle._GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark, Boolean loadTypeFromPartialName) +0
System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark) +64
System.RuntimeType.PrivateGetType(String typeName, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark) +58
System.Type.GetType(String typeName, Boolean throwOnError) +59
System.Web.UI.DataVisualization.Charting.ChartHttpHandlerSettings.get_HandlerType() +61
System.Web.UI.DataVisualization.Charting.ChartHttpHandlerSettings.InspectHandlerLoader() +37
System.Web.UI.DataVisualization.Charting.ChartHttpHandlerSettings.Inspect() +1167
System.Web.UI.DataVisualization.Charting.ChartHttpHandlerSettings.ParseParams(String parameters) +1401
System.Web.UI.DataVisualization.Charting.ChartHttpHandlerSettings..ctor(String parameters) +397
System.Web.UI.DataVisualization.Charting.ChartHttpHandler.InitializeParameters() +155
System.Web.UI.DataVisualization.Charting.ChartHttpHandler.EnsureInitialized(Boolean hardCheck) +314
System.Web.UI.DataVisualization.Charting.ChartHttpHandler.EnsureInstalled() +27
System.Web.UI.DataVisualization.Charting.Chart.GetImageStorageMode() +46
System.Web.UI.DataVisualization.Charting.Chart.Render(HtmlTextWriter writer) +201
System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +27
System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +99
System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +25
System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +134
System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +19
System.Web.UI.HtmlControls.HtmlForm.RenderChildren(HtmlTextWriter writer) +163
System.Web.UI.HtmlControls.HtmlContainerControl.Render(HtmlTextWriter writer) +32
System.Web.UI.HtmlControls.HtmlForm.Render(HtmlTextWriter output) +51
System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +27
System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +99
System.Web.UI.HtmlControls.HtmlForm.RenderControl(HtmlTextWriter writer) +40
System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +134
System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +19
System.Web.UI.Page.Render(HtmlTextWriter writer) +29
System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +27
System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +99
System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +25
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1266
Any thoughts?
Thanks,
Kevin