Introduction

This is a SharePoint WebPart that will enable site administrators to add dynamically generated Crystal Reports to SharePoint web pages without any programming required. The Web Part part is written in C# with .NET Framework 3.5 (should be OK with .NET Framework 2.0).

Background

I was recently asked by a client to write a Web Part that would allow them to dynamically generate and display Crystal Reports for their production control team. The crucial aspect being that the report had to be generated from the latest continually changing information; reports generated overnight and stored in a document library would not be acceptable. Having implemented this for the relatively limited number of reports required, by hard coding the physical location of the Crystal Report definition file, it seemed that a more generalised version that would allow the report definition files to be uploaded to and stored in a SharePoint Document Library and placed on a page by the site administrator would be a useful utility.

It is assumed that you have a basic understanding of SharePoint Web Part development.

Set up a Crystal Reports Document Library

In SharePoint, add a document library for the Crystal Reports definition files (.rpt). By default, this is called "Crystal Reports RPT Files". You can change this to suit your own requirements, but you will then need to change the library name in the source code. Upload one or more RPT files to the document library. The RPT files must be written to access the target database directly; the code could be rewritten to access a local dataset, but this is not currently supported.

The Code

Create a SharePoint Web Part

In Visual Studio, click on File, New, Project, SharePoint, and select Web Part. Give the project a suitable name and location, and click OK.

In Solution Explorer, right click on References, and add references to the Crystal Reports libraries. You will need the following:

Open the aspx.cs source file for the Web Part, and add using statements for the above:

using CrystalDecisions.Shared;
using CrystalDecisions.CrystalReports.Engine;
using CrystalDecisions.Web;

We need to be set a property holding the name of the report file the Web Part will use. This is serialised with the get/set methods in public string ReportSource.

publicclass CustomCrystalReportWP : System.Web.UI.WebControls.WebParts.WebPart
{
// for the name of the .rpt file in the document library
String strReportName = "";
// an editor part control to display a list of reports
ReportSourcePart edPart = new ReportSourcePart();
public CustomCrystalReportWP()
{
}
// to serialise the name of the report
[Personalizable(PersonalizationScope.Shared, false)] // Storage.
publicstring ReportSource
{
get
{
return strReportName;
}
set
{
strReportName = value;
}
}

In CreateChildControls, add a CrystalReportViewer and a Crystal Reports document. Find the .rpt file in the SharePoint document library, as Crystal Reports will only open an .rpt file from a physical file, write it to a temporary file, which is then set as the location of the temporary file in the CR document.

Set up up the Tool pane, which is displayed when the Web Part is edited, so that the report can be selected. This is pretty much SharePoint Web Part boiler plate code; the selected filename gets saved in the base Web Part.

You can now build the Web Part and try adding it to a SharePoint Web Part page. In Visual Studio 2008, the retract, create, and deploy solution steps have been automated, so you can simply click on the Debug button and your site should open, and you can try the Web Part by adding it to a Web Part page. There are, however, two apparent problems. There are no glyphs on the toolbar, and any graphics (graphs, charts) don't display. All you see is a box with a red X in it.

To fix these problems:

The toolbar glyphs need some files installed on the root website to be available in the SharePoint web site files. Copy from:

Paste the files to:

Fixing the graphics not displaying problem is more complicated.

Digging around on the net finds a number of references to the problem which seems to be generally regarded as caused by the Crystal Reports dynamic image HttpHandler (CrystalImageHandler.aspx) being called out of sequence so that its output is never displayed. The most satisfactory solution I could come across was developed from a hint by an observant developer, that Crystal Reports wrote a temporary file in "c:\windows\temps\cr_tmp_image__yoursite" and that the problem could be fixed by having a source code CrystalImageHandler.aspx and its code-behind file in the root folder of your SharePoint web site that sends the temporary file using Response.Transmitfile back to the client, which fixes the out of sequence call.

Copy the two files CrystalImageHandler.aspx and CrystalImageHandler.aspx.cs which I have included in the source file for simplicity, and paste them in the root folder of your site, which for example could be:

c:Inetpub\wwwroot\wss\VirtualDirectories\80

When the page is loaded to display your graphic image, it is compiled dynamically, and you can debug it from within Visual Studio, but only if it compiles successfully. You will not see any compilation errors from within Visual Studio, you need to look in Administration Tools/Event Viewer/Applications and look for errors or warnings, which should allow you to fix any problems.

Here is the CrystalImageHandler.ascx file:

The Register Assembly instances above are required to handle references to Crystal Reports DLLs. To copy the above code, you will need to download the source files.

The C# file builds the name of the temporary file and sends it back to the client.

Using the Code

You can install the WebPart on your site by copying the source code, or by installing the WSP file in the CRWPCompiledInstall.zip download. The simplest way to install compiled Web Parts is by using the stsadm command line utility which can be found, by default, in: C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN\stsadm.exe.

From a command prompt, with suitable adjustments for file paths, run:

stsadm -o addsolution -filename CustomCRWPInstall.wsp

You will also need to copy the two files CrystalImageHandler.ascx and CrystalImageHandler.ascx.cs to the root folder of your web site (see above for the default path).

Points of Interest

Integrating complicated applications such as SharePoint and Crystal Reports can be a frustrating and time consuming job. Sometimes you can get lucky, and things just work (like they're supposed to), but often they don't, and if no solution is easily found on the net, you are faced with the choice of what could be a long series of trial and error experiments to find an answer, or a long task of study and research to become at least a partial expert on the technologies you are working with, for which you often find you simply don't have the time.

Comments and Discussions

i used the code to integrated the web part into my sharepoint app. but after that i got the problem below : when i click any item of the group tree or search any item use the search button. the page will go to the item that i want, but the item displayed on the top of the page , so the bottom of the page will be a blank white that is the whole page slide up and con not come back except refreshing the page. it make me confused for a long time, can somebody help me with this or give me some advice.

I am trying to use this on a Sharepoint 2010 server.I have the wsp file added and deployed, but when I try to go an add it to the library page, I cannot see it in the list.Is there something else that needs to doing to make it visible?

1.Log on to the sharepoint site where u want that webpart. 2.Go to site settings 3.Under Galleries, click on web parts. 4.In the webpart Gallery, Click on New 5.You find find a list of webparts now. Select the webpart which you have added and click populate gallery button 6.Now you will get the webpart in the webparts list under misc

The solution works fine when logged in as the Sharepoint administrator but whenever any other user tries to access the page with the CR web part they get an Error 403 saying the user is required to log in even though the user is logged into Sharepoint and has the necessary access permissions. I suspect this is an underlying access issue on the server file system. Anyone else had the same problem and knows of a solution?

Can the .wsp solution be deployed in a Windows Server 2003 that only has installed MOSS 2007(Microsoft Office SharePoint Server) but doesn't have any version of Visual Studio installed? If it can be deployed; what are the steps to do so?

I deployed successfully your .wsp solution using the stsadm.exe method, but when I open my Sharepoint site and access "Site Settings/Site collection features" there's no new feature listed and there's no new webpart object in the "Add a Webpart" dialog window.

Same Issue ran Stsadm then went into Central Administration and deployed the solution which ran perfectly but still no feature or webpart???? What gives???? Are we missing a step here? Win2008Server r2, SqlSrvr 2008 r2, WSS3.0 (cause its still free)

I was having the same problem because I hadn't loaded the old version.

I had installed the CR for VS2k10 beta which had the non-existant reference assembly version 14.0.2000.0 and using the app.config/web.config to "reversion" it to the is-existant version 12.0.200.0 as per CR's docs.

I was getting that to work but you have to deal with the serialization issue, and being lazy, I just stuck the version 10.5.3700.0's in and it worked like a charm.

You can just manually add them to VS2k10, but be sure to remove the old ones and re-select ony the v10.5.3700 ones (ie: you'll see 3 CrystalDecisions.Web's in the .Net 3.5 list - one for 10, 12, and 14, so pick the 10).

I have the same problem, but I don't understand the answer that you provide. Pardon me, I am a newbie.

1. I install the Beta 2, do we need to change the app.config/web.config to "reversion" it to the is-existant version 12.0.200.0? But I did not see the app.config or web.config when I create a webpart project, do I need to add the files, or the files exists somewhere else?

2. How to add old ones to VS2010, so you mean to add as reference in the project? I don't have the old version crystal, do I need to install the old version on the machine? How to add the old version to vs2010?

I too have the same problem in dispalyging the images. I follwed the article and

a. copied all the files as mentioned in the step one b. copied the CrystalImageHandler.Aspx and CrystalImageHandler.Aspx.Cs file as mentioned in the step 2 c. finally gaced the assembly and restart the IIS

I too have the same problem. The red image just won't go away despite having tried a multitude of things including those from SAP's Senior Customer Assurance technical expert.

The dynamic images are not displaying although I have seen them in the folder c:\Windows\Temp\cr_tmp_image__it_80.

I am using Crystal Reports 2008 but I also have Business Objects XI release 2 installed as a client installation. I have the BusinessObjects.Enterprise.WCA.dll in my GAC after copying it from our server machine.

My IIS has two virtual folders: CrystalReportsViewers115 and CrystalReportsViewers115.

I created the Webpart using Visual Studio 2005.

The red X image appears in place of any dynamic images in my Crystal Report. I have modified the config file located at C:\Inetpub\wwwroot to include the foll

The root folder of my application is c:Inetpub\wwwroot\wss\VirtualDirectories\46065.

I have tried various things such as adding the following httpHandler to no avail:

I follow this post to do Crystal Reports WebPart for SharePoint, and it really work, I am so happy.

But, I have a problem, when i use sharepoint API to get list data, and sotre in dataset, and then I write "crdoc.SetDataSource(ds)", the webpart don't work. the error message is : CrystalDecisions.CrystalReports.Engine.LoadSaveReportException: Load report failed

Can anyone help me with this ? I will really appreciate your kind help.

When I try to open CustomCRWP.csproj from CustomCRWP source folder, the error message "the CustomCRWP.csproj cannot be opened because its project type(.csproj) is not supported by this version of the application".I'm using

It was written with VS 2008. VS 2008 are not backwards compatible with VS 2005, you would need to rebuild the project for VS 2005. Create a new project in VS 2005 and copy files and resource to the project directory and use 'Add existing item' to install them in your project.

I have issue with any authentication being passed through.Report runs fine on desktop using credentials (using OLE DB by the way), however it won't accept the same credentials in the web part - just keeps refreshing the page with no error logged anywhere...

I am having the same file Not Found error as another. I cannot get any error messages or anything to show what the specific issue is. I am a novice coder and familiar with ASP.net and C#, but not familiar with the structure of Sharepoint. Any ideas on how to get an error message or log so I can see what the issue is?

I've got the same issue. I have installed both Crystal Reports 9 and Crystal Reports 10 and do not have the assemblies in my References .NET tab. I've tried searching and can't find the files on C: either

If you have an install somewhere else, you can manually copy them to the reference assembly folder (there are plenty of tute's if you just goog it).

Now before you do all that, there is actually a serialzation error you'll get with V14(v12) - so I recommend just installing the CR assemblies from VS2k8 (version 10.5.3700.0) and it should complie without a hitch. Try the link below for the CR integration kit for VS2k8.

Do you know off a way where a sharepoint admin can create new crystal reports from data coming from a webservice and this while he is on a sharepoint page, like a dashboard page? Does this sound like functionality that can be accomplished in sharepoint?

I am sure you could do this but you would need to do some coding.I would try saving the data from the web service in a tempory file or database table that Crystal could build reports from, and then run your report in Sharepoint as in the article.I don't know of any off the shelf functionality that would achieve this for you.

Having a .rpt file in the doclib shouldn't be necessary.Not finding the CustomCrystalReportWP file when trying to add the webpart to a page could be an authorisation problem. Is the user you are logged in as, authorized to add a web part ?Check for messages in the event log.

thanks for your reply.I am a site content administrator in Sharepoint, and member of Owners group, and local admin on the server (which might not be enough), and I logged in as that account.That "should" be sufficient to install new web parts to the gallery.Incidentally, when I try to click on the web part link in the gallery, I get the same error.When I ran the install for the webpart using stsadm -o addsolution I received a success message.I also received a success message for the deployment of the solution.When I get the "file not found" error, there is no event log message is generated.Which is curious to me.I checked the file permissions for the two additional files that are added to the root.The permissions look fine. It is almost as if the server does not have access to the GAC for that particular web part.Yes, I agree it is probably a file auth type of problem.I shouldn't need to modify the sharepoint security model in web.config, but I think I will set it to "FULL" and see if that resolves the problem, and then set it back, as I don't want the server to run in FULL trust mode. At least I will know at that point if it is sharepoint or something about the file system.-dw

Sorry for the late reply, I've been out of contact for a few days.If the web part is running from the GAC it probably needs a strong name, which as it stands it doesn't have. I wonder if setting it up with a strong name would get it to work ?

I turned off the custom errors and now I received a more meaningful message:

File Not Found. at CustomCRWP.CustomCrystalReportWP.CreateChildControls() at System.Web.UI.Control.EnsureChildControls() at System.Web.UI.Control.PreRenderRecursiveInternal() at System.Web.UI.Control.PreRenderRecursiveInternal() at System.Web.UI.Control.PreRenderRecursiveInternal() at System.Web.UI.Control.PreRenderRecursiveInternal() at System.Web.UI.Control.PreRenderRecursiveInternal() at System.Web.UI.Control.PreRenderRecursiveInternal() at System.Web.UI.Control.PreRenderRecursiveInternal() at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)