|
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!
|