WalterRautenbach
asked on
Load report failed
Hello,
I am receiving a "Load report failed" error when i try viewing reports on my website that contains embedded Crystal reports. When i begun receiving these errors, cleared out the temp folder "C:\WINDOWS\Temp", assigned modify, read write rights to IIS/WPG, set impersonate="false" in my web config file, and it still didn't help and my code also caters for closing and disposing the report and utilizes the garbage collector. So i restarted IIS, which did do the trick, but is there any other way of prevent this error from occuring again, instead of restarting IIS, since my website utilizes sessions, and session values will be lost.
I am receiving a "Load report failed" error when i try viewing reports on my website that contains embedded Crystal reports. When i begun receiving these errors, cleared out the temp folder "C:\WINDOWS\Temp", assigned modify, read write rights to IIS/WPG, set impersonate="false" in my web config file, and it still didn't help and my code also caters for closing and disposing the report and utilizes the garbage collector. So i restarted IIS, which did do the trick, but is there any other way of prevent this error from occuring again, instead of restarting IIS, since my website utilizes sessions, and session values will be lost.
public ReportDocument myReport;
protected void Page_Unload(object sender, EventArgs e)
{
if (myReport!= null)
{
myReport.Close();
myReport.Dispose();
}
GC.Collect();
}
ASKER
Thank you for the comment, what does the "key" reference, i understand the "path" is the path of the .rpt file.
actually that was not a good and full example, let me give you class code which I am using in my production. You can generate one class file for this and use it.
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections.Generic;
using CrystalDecisions.CrystalReports.Engine;
using System.IO;
using System.Text;
using System.Web.Caching;
using System.Diagnostics;
/// <summary>
/// Summary description for ReportDocumentFactory
/// </summary>
public class ReportDocumentFactory
{
//Crystal printJobLimit key is in registry:
//HKEY_LOCAL_MACHINE\SOFTWARE\Crystal Decisions\10.2\Report Application Server\Server\PrintJobLimit
const int CRYSTAL_PRINT_JOB_LIMIT = 75; //default value is 75, it must by sincronized with registry!
const string REPORT_DOCUMENT_CAHE_KEY = "ReportDocumentQueue";
private Dictionary<string, ReportDocumentInfo> docList;
public ReportDocumentFactory(Cache cache)
{
try
{
docList = (Dictionary<string, ReportDocumentInfo>)cache[REPORT_DOCUMENT_CAHE_KEY];
}
catch (InvalidCastException ex)
{
//if generic dictionary is compiled dinamically, we must clean report cache.
//This has a problem, because the processed reports are not disposed, this case
//should not happen to.
cache.Remove(REPORT_DOCUMENT_CAHE_KEY);
docList = null;
}
if (docList == null)
{
docList = new Dictionary<string, ReportDocumentInfo>(CRYSTAL_PRINT_JOB_LIMIT);
cache.Add(REPORT_DOCUMENT_CAHE_KEY, docList, null, Cache.NoAbsoluteExpiration, new TimeSpan(0, 20, 0),
CacheItemPriority.AboveNormal, new CacheItemRemovedCallback(this.CacheRemovedCallback));
}
}
public string Add(ReportDocument reportDoc)
{
Debug.WriteLine("Add() called.");
if (docList.Count + 1 >= CRYSTAL_PRINT_JOB_LIMIT)
{
Debug.WriteLine("Add() CRYSTAL_PRINT_JOB_LIMIT Reached.");
try
{
//dequeue de old one (FIFO)
List<ReportDocumentInfo> rInfoSortList = new List<ReportDocumentInfo>(docList.Values);
rInfoSortList.Sort(delegate(ReportDocumentInfo rInfo1, ReportDocumentInfo rInfo2)
{
return DateTime.Compare(rInfo1.Date, rInfo2.Date);
});
Remove(rInfoSortList[0].Key);
}
catch (Exception e)
{
//TODO: log
Debug.WriteLine("Add() error: " + e.Message);
try
{
Remove(docList.Keys.GetEnumerator().Current.ToString());
}
catch { }
}
}
string key = Guid.NewGuid().ToString();
docList.Add(key, new ReportDocumentInfo(key, reportDoc));
return key;
}
public void Remove(string key)
{
Debug.WriteLine("Remove() called.");
if (key != null)
{
try
{
ReportDocumentInfo reportInfo = docList[key];
DisposeReportDocument(reportInfo);
docList.Remove(key);
}
catch (Exception e)
{
Debug.WriteLine("Remove() error: " + e.Message);
}
}
else
{
Debug.WriteLine("Remove() error: null key");
}
}
public bool Contains(string key)
{
return docList.ContainsKey(key);
}
public ReportDocument GetValue(string key)
{
ReportDocumentInfo value = null;
if (docList.TryGetValue(key, out value))
{
if (value != null)
return value.ReportDoc;
else return null;
}
else
{
return null;
}
}
protected void DisposeReportDocument(ReportDocumentInfo reportInfo)
{
try
{
if (reportInfo != null)
{
//Need to dispose document, crystal has a limit for number of loaded reports
reportInfo.ReportDoc.Close();
reportInfo.ReportDoc.Dispose();
}
}
catch (Exception e)
{
//TODO: log
Debug.WriteLine("DisposeReportDocument() error: " + e.Message);
}
}
//Release crystal resources when cache is clean
public void CacheRemovedCallback(string key, Object value, CacheItemRemovedReason reason)
{
Debug.WriteLine("CacheRemovedCallback() called, reason: " + reason.ToString());
try
{
if (docList != null)
{
Debug.WriteLine("CacheRemovedCallback() cleaning ressources " + docList.Count);
Dictionary<string, ReportDocumentInfo>.ValueCollection valueColl = docList.Values;
foreach (ReportDocumentInfo reportDocInfo in valueColl)
{
DisposeReportDocument(reportDocInfo);
}
}
}
catch
{
Debug.WriteLine("CacheRemovedCallback() error.");
}
}
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thank you!!!
ASKER
What is the namespace for ReportDocumentInfo? I am getting the following error '"The type or namespace name 'ReportDocumentInfo' could not be found (are you missing a using directive or an assembly reference" when i try compiling your code.
no namespace for that. You have to create on separate class for the code I gave you in post id 24085797. I have created ReportDocumentFactory.cs file under my APP_code folder of my website.
ASKER
i have created a separate class, but i get the following error "The type or namespace name 'ReportDocumentInfo' could not be found (are you missing a using directive or an assembly reference"
where did you put that class? and what is the name you gave to that class? I would recommend you to put it under app_code folder in root of your web directory. and give it a name ReportDocumentFactory.cs. Once you generate ReportDocumentFactory.cs file, copy my code which is in post # 24085797 and paste it in ReportDocumentFactory.cs
ASKER
I created the class within the root directory and the class is within the App_Code folder. Is the 'ReportDocumentInfo' a variable which supposed to be declared with the class? Dictionary<string, string> so I presume 'ReportDocumentInfo' is a string?
reportdocumentinfo is another class and again needs to be save under app_code folder with name ReportDocumentInfo.cs
sorry I forget to attach its code before. below given is the code. Moreover, don't put any class under direct root folder
sorry I forget to attach its code before. below given is the code. Moreover, don't put any class under direct root folder
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections.Generic;
using CrystalDecisions.CrystalReports.Engine;
using System.IO;
using System.Text;
using System.Web.Caching;
using System.Diagnostics;
/// <summary>
/// Summary description for ReportDocumentInfo
/// </summary>
public class ReportDocumentInfo
{
private string key;
private ReportDocument reportDocument;
private DateTime date;
public ReportDocumentInfo(string key, ReportDocument reportDocument)
{
this.key = key;
this.reportDocument = reportDocument;
this.date = DateTime.Now;
}
public ReportDocument ReportDoc
{
get
{
return this.reportDocument;
}
set
{
this.reportDocument = value;
}
}
public DateTime Date
{
get
{
return this.date;
}
set
{
this.date = value;
}
}
public string Key
{
get
{
return this.key;
}
}
}
ASKER
thank you, makes much more sense now. Another thing i want to ask you is, when you instantiate the class ReportDocumentFactory, was it not suppose to be as follows
ReportDocumentFactory reportDocumentFactory=new ReportDocumentFactory (cache);
since the class ReportDocumentFactory expects an argument.
I have added your code and it is still not functional, therefore i am asking this question.
ReportDocumentFactory reportDocumentFactory=new ReportDocumentFactory (cache);
since the class ReportDocumentFactory expects an argument.
I have added your code and it is still not functional, therefore i am asking this question.
yes you can do like that also
ReportDocumentFactory reportDocumentFactory = new ReportDocumentFactory(this .Cache);
in aspx code I gave you, I have delare the class first and that instantiated. but you can do it in same line.
ReportDocumentFactory reportDocumentFactory = new ReportDocumentFactory(this
in aspx code I gave you, I have delare the class first and that instantiated. but you can do it in same line.
http://www.crystalreportsbook.com/Forum/forum_posts.asp?TID=1205
Open in new window