HttpHandler and Deployment Issues
INTRODUCTION
The WebViewer control has been associated with ActiveReports for a long time. With the passage of time, there have been many enhancements made to it terms of both features and performance. Currently in ActiveReports 8, the WebViewer offers four different types of viewers to choose from: RawHtml, Html, Acrobat Reader and the FlashViewer.
COMMON ERRORS
A very common problem which developers report is that the WebViewer works fine on the development machine but upon deploying the application, the WebViewer control either does not render or they get some error messages which are not very informative. Below are some common error messages:
- "OpenedReport is undefined" This is a common error when the "FlashViewer" is used as the viewer type in the WebViewer.
- "ViewerViewModel is undefined" This error is similar to the first error except for that it occurs when "Acrobat Reader" is set as the viewer type in the WebViewer.
- "IOError while loading document. Reason: Error #2032" All these errors have a common cause and it is the incorrect handler mappings. But before looking at the resolution, it is important to understand about the HttpHandlers and their role. So let's check it out.
UNDERSTANDING HTTP_HANDLERS
You might have noticed that whenever we add a WebViewer control to the ASPX page, the "GrapeCity.ActiveReports.Web.v8.dll" gets added to the project. This is because its dependency contains the JavaScript libraries which are required during the rendering of the WebViewer control. If the page cannot find or load any of these libraries, the aforementioned errors may occur. Also in case of "HtmlViewer" type, the toolbar will not render correctly, even if an error does not occur. This is where HttpHandlers come to the rescue. If we check the MSDN link regarding HttpHandlers, we will see that _"An ASP.NET HTTP handler is the process (frequently referred to as the "endpoint") that runs in response to a request made to an ASP.NET Web application." _Here is how the calls are made to the webserver for ActiveReports javascript libraries. This is a screenshot from the FireBug's Net tab: As you can see in the image, all the requests for scripts ends with an extension ".ar8" which is not a standard web extension. The role of HttpHandlers is to recognize these extensions and redirect it to the correct dll so that required response can be returned from the webserver. However, the request must first make it to the asp.net engine in order for the web.config file to be able to handle the request. This means that IIS must either pass all extensions through to the asp.net engine, or have the .ar8 extension added to it's list. So we need to add the HttpHandlers either directly to the IIS or to through the web.config file. We will check the latter approach in the next section.
CONFIGURING HANDLER MAPPINGS
In IIS7 and later, users can select from two different Application Pools viz Classic Mode and Default App Pool (Integrated Pipeline Mode). When selecting a particular application pool, the handlers also need to be configured accordingly. Let's take a look at them one by one.
Classic Mode
The HttpHandlers are to be added inside the httpHandlers tag which is under <system.web> and handlers tag which is under <system.webServer>. Below is the corresponding snippet from the web.config file.
<system.web>
<httpHandlers>
<add verb="*" path="*.asmx" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false" />
<add verb="*" path="*.ar8" type="GrapeCity.ActiveReports.Web.Handlers.ReportBinariesStreamer, GrapeCity.ActiveReports.Web.v8, Version=8.1.414.0, Culture=neutral, PublicKeyToken=cc4967777c49a3ff" />
<add verb="*" path="*.ActiveReport" type="GrapeCity.ActiveReports.Web.Handlers.CompiledReportHandler, GrapeCity.ActiveReports.Web.v8, Version=8.1.414.0, Culture=neutral, PublicKeyToken=cc4967777c49a3ff" />
<add verb="*" path="*.rpx" type="GrapeCity.ActiveReports.Web.Handlers.RpxHandler, GrapeCity.ActiveReports.Web.v8, Version=8.1.414.0, Culture=neutral, PublicKeyToken=cc4967777c49a3ff" />
<add verb="*" path="*.rdl,*.rdlx" type="GrapeCity.ActiveReports.Web.Handlers.RdlxHandler, GrapeCity.ActiveReports.Web.v8, Version=8.1.414.0, Culture=neutral, PublicKeyToken=cc4967777c49a3ff" />
<add verb="*" path="*.ar8Web" type="GrapeCity.ActiveReports.Web.Handlers.WebCacheAccessHandler, GrapeCity.ActiveReports.Web.v8, Version=8.1.414.0, Culture=neutral, PublicKeyToken=cc4967777c49a3ff" />
</httpHandlers>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<handlers>
<add name="AR8Rpx" path="*.rpx" verb="*" modules="IsapiModule" scriptProcessor="%windir%\\Microsoft.NET\\Framework\\v4.0.30319\\aspnet_isapi.dll" />
<add name="AR8Rdlx" path="*.rdlx" verb="*" modules="IsapiModule" scriptProcessor="%windir%\\Microsoft.NET\\Framework\\v4.0.30319\\aspnet_isapi.dll" />
<add name="AR8Rdl" path="*.rdl" verb="*" modules="IsapiModule" scriptProcessor="%windir%\\Microsoft.NET\\Framework\\v4.0.30319\\aspnet_isapi.dll" />
<add name="AR8" path="*.ar8" verb="*" modules="IsapiModule" scriptProcessor="%windir%\\Microsoft.NET\\Framework\\v4.0.30319\\aspnet_isapi.dll" />
<add name="AR8Web" path="*.ar8Web" verb="*" modules="IsapiModule" scriptProcessor="%windir%\\Microsoft.NET\\Framework\\v4.0.30319\\aspnet_isapi.dll" />
<add name="ActiveReport" path="*.ActiveReport" verb="*" modules="IsapiModule" scriptProcessor="%windir%\\Microsoft.NET\\Framework\\v4.0.30319\\aspnet_isapi.dll" />
</handlers>
</system.webServer>
An important thing to take into account is the version of ActiveReports 8 should match the one being used in the application and the .NET framework version should be correct. A sample web.config file can be downloaded from the download link below:
Integrated Pipeline Mode
You need to add the following handler mappings for Integrated Pipeline Mode:
<system.web>
<httpHandlers>
<add verb="*" path="*.asmx" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false" />
<add verb="*" path="*.ar8" type="GrapeCity.ActiveReports.Web.Handlers.ReportBinariesStreamer, GrapeCity.ActiveReports.Web.v8, Version=8.1.414.0, Culture=neutral, PublicKeyToken=cc4967777c49a3ff" />
<add verb="*" path="*.ActiveReport" type="GrapeCity.ActiveReports.Web.Handlers.CompiledReportHandler, GrapeCity.ActiveReports.Web.v8, Version=8.1.414.0, Culture=neutral, PublicKeyToken=cc4967777c49a3ff" />
<add verb="*" path="*.rpx" type="GrapeCity.ActiveReports.Web.Handlers.RpxHandler, GrapeCity.ActiveReports.Web.v8, Version=8.1.414.0, Culture=neutral, PublicKeyToken=cc4967777c49a3ff" />
<add verb="*" path="*.rdl,*.rdlx" type="GrapeCity.ActiveReports.Web.Handlers.RdlxHandler, GrapeCity.ActiveReports.Web.v8, Version=8.1.414.0, Culture=neutral, PublicKeyToken=cc4967777c49a3ff" />
<add verb="*" path="*.ar8Web" type="GrapeCity.ActiveReports.Web.Handlers.WebCacheAccessHandler, GrapeCity.ActiveReports.Web.v8, Version=8.1.414.0, Culture=neutral, PublicKeyToken=cc4967777c49a3ff" />
</httpHandlers>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<handlers>
<add verb="*" path="*.asmx" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" name="AsmxHandler" resourceType="Unspecified" preCondition="integratedMode" />
<add verb="*" path="*.ar8" type="GrapeCity.ActiveReports.Web.Handlers.ReportBinariesStreamer, GrapeCity.ActiveReports.Web.v8, Version=8.1.414.0, Culture=neutral, PublicKeyToken=cc4967777c49a3ff" name="AR8_ReportBinariesStreamer" resourceType="Unspecified" preCondition="integratedMode" />
<add verb="*" path="*.ActiveReport" type="GrapeCity.ActiveReports.Web.Handlers.CompiledReportHandler, GrapeCity.ActiveReports.Web.v8, Version=8.1.414.0, Culture=neutral, PublicKeyToken=cc4967777c49a3ff" name="AR8_CompiledReportHandler" resourceType="Unspecified" preCondition="integratedMode" />
<add verb="*" path="*.rpx" type="GrapeCity.ActiveReports.Web.Handlers.RpxHandler, GrapeCity.ActiveReports.Web.v8, Version=8.1.414.0, Culture=neutral, PublicKeyToken=cc4967777c49a3ff" name="AR8_RpxHandler" resourceType="Unspecified" preCondition="integratedMode" />
<add verb="*" path="*.rdl,*.rdlx" type="GrapeCity.ActiveReports.Web.Handlers.RdlxHandler, GrapeCity.ActiveReports.Web.v8, Version=8.1.414.0, Culture=neutral, PublicKeyToken=cc4967777c49a3ff" name="AR8_RdlxHandler" resourceType="Unspecified" preCondition="integratedMode" />
<add verb="*" path="*.ar8Web" type="GrapeCity.ActiveReports.Web.Handlers.WebCacheAccessHandler, GrapeCity.ActiveReports.Web.v8, Version=8.1.414.0, Culture=neutral, PublicKeyToken=cc4967777c49a3ff" name="AR8_WebCacheAccessHandler" resourceType="Unspecified" preCondition="integratedMode" />
</handlers>
</system.webServer>
A sample web.config file can be downloaded from the download link below: So this brings us to the end. Please note that the above entries are tested on a 32 bit machine and are meant to be used on a machine with similar OS configuration.