Main
    Home Page
    Resume
    Contact Me
  Sprocgen
    News
    Features
    Screenshots
    Download
  Gammaworld
    News
    Features
    Screenshots
    Download
  Articles
    Properties of
    a Crystal Web
    Services
    Website Monitor

Properties of a Crystal Web Services
October 1st 2003
John Lien

In the .NET environment I am still amazed at the things you can do with it, there is no end to the possibilities. I recently developed a set of Crystal Reports for a company. The requirements were that the work load of creating that report be on an application server away from the web server. I found an easy way to do this, Web Services and Crystal Reports in .NET!

Now, I built these Crystal Reports using datasets due to the fact I really like the notion of using them as the data glue for building the report. This keeps us from having all those login problems, and allows us to build a dataset outside Crystal Reports by any means and feed that to the report.

And here in lies the problem, if anyone has tried to do this before. Let’s say the client application that’s calling the Crystal Reports Web Service is required to send parameters to that service so that you can construct your dataset. Lets say start and end date, I was unable to find a way to modify the Crystal Reports Web Service that was created to do what I wanted.

I know you can enable sessions and keep state in a web service, although most people would say this shouldn’t be done for scalability reasons and I wanted to keep that in mind as well. I wrote a test web service to have a public web method that sets some properties on the web service using sessions, then called another method and accessed those session variables and it worked. The one thing I couldn’t make work was getting sessions enabled on a crystal web service in the OnInitReport() stateful using the [WebMethod(EnableSession=true)] aparently Crystal doesnt like that.So I came up with a way to utilize the HTTP protocol to my advantage.

So for my implementation I needed a start date and end date to be passed to the Crystal Report Web Service to ensure that it only returned data between certain dates and times. The proxy classes for web services in .NET have a property called CookieContainer which holds cookies for that instance of the proxy class and all communications to that web service for the life of that instantiated class.

Code listed below is modified from original form just to illustrate, and is part of the client calling the web service:

Cookie aCookie = new Cookie( "EndDate", "9/1/2003", "/", "localhost");
Cookie bCookie = new Cookie( "StartDate", "9/1/2003", "/", localhost");
CookieContainer myContainer = new CookieContainer();
myContainer.Add(aCookie);
myContainer.Add(bCookie);

WS.ReportService WS1 = new WS.ReportService();
WS1.CookieContainer = myContainer;
CrystalReportViewer1.ReportSource = WS1;

As you can see, this creates two cookies with the domain of the localhost, notice everything is being hosted on my local box, both the service and the client so you will need to change this in a live environment. Then it creates an instance of the proxy class, and sets its cookie container equal to the cookie container that was created.

Now Crystal Web Services has a method OnInitReport() which is run when you initialize the report over the web service. This is called under the hood, so all you have to do is put your binding code in there and your set. To get the cookies you set on the client here in the service, you would do it like this (keep in mind you need System.Web imported):

HttpCookieCollection myCookies = HttpContext.Current.Request.Cookies;

Then you can get the cookies with the standard cookie call:

myCookies["StartDate"].Value

I had been reading all over the newsgroups and every website I could get my hands on and couldn’t find anything like this. Nothing that showed me how I would modify the Crystal Web Service to be stateful or to handle parameters I could send it to create my own dataset and bind it rather than having pre-set database connections, logins, and using the parameters built into Crystal.

I would love to hear if someone has a better way to accomplish this, but I am glad I went down this road as I learned quite a bit about Web Services in general and Crystal’s implementation of Web Services in the .NET environment. Any comments, flames or questions please feel free to contact me at my contact link above!