Hi,
I'm currently developing an application for SmartClient wherein I must call a webservice to access my database.
I would like to have the business objects seamless to the user. That is, if the user calls Project.GetProject(id), the class will call the webservice to access the database, and populate the instance. No problem there, my DataPortal_XYZ methods simply call a webservice.
However, to make things simpler for the developers, I'd like to use the same classes when developing the webservice.This webservice is NOT a data portal. I'm not using WS instead of remoting.
That is, Project.GetProject(id) when called on the client, will call the underlying WS layer, whereas in the ASP.NET Webservice, it will access the database.
I will be using classes akin to ProjectData (From Chapter 11), to return the data.
Has anyone tried this?
I'm using the MS ServiceInterface pattern for my service, and would like to also implement that interface on the client. This will provide the consistency that I need, and hopefully not at the cost of complexity.
Many thanks,
Sean
Sean D:
That is, Project.GetProject(id) when called on the client, will call the underlying WS layer, whereas in the ASP.NET Webservice, it will access the database.
Hi,
I have a Winforms app only. I;m developing an ASP.NET WebService. I can't use the DataPortal as a webservice (CRUD functions). My webservice may be used by other apps.
However, when I use the webservice from my application (Winforms), I'd like to use the same class library that I used in the actual webservice. When the static methods, e.g. GetProject(), are called on the client, the DataPortal_XYZ methods will call the webservice, and when the same methods are called in the webservice gateway, the methods will access the database via ADO.NET.
I would like to use the webservice dataportal to create, update, etc from my client, but that's not an option, as future clients will be unaware of this functionality, and will access the webservice methods directly. These will be methods like GetProject(), GetProjectList(), and will return typed data (that's described in the WSDL).
I hope that clarifies things somewhat.
Thanks,
Sean
It seems to me (and trust me, I am no expert as I am only now venturing into this area myself), that the only conflict that you have is differentiating the call on the client which is to pass the request onto the web service and the call on the server that is to perform the data access and return the desired BO. Isn't this handled by the web service itself?
What I mean is, when you call Projects.GetProjectList() on the client, even though it seems like you are calling your BO directly, you are calling a proxy created for your web service. The web service handles the fact that this call has occurred on the client and passes the call onto the server-side web service. The body of the method actually executes on the server so you can easily implement whatever data access code you need - in fact, this is where you would implement the data portal to allow for a distributed architecture on the server(s).
As such, your application is actually entirely on the server. What you have done is exposed a service interface, via the web service to allow client applications to hook into the application.
Now, the catch is, at least as far as my knowledge goes, is determining the proper way to work with the returned objects. The "object" that is returned from the web service is coming across in an XML serialized format. So, the proxy should be able to deserialize the stream into the BO on the client so that it can be used as expected. You'll just have to have the client app reference the class library that contains the class definitions.
Oh, one other thought, to simplify the logic we are considering that it might be easier to use a factory to serve as the interface to the WS rather than the BO. So, instead of Projects.GetProjectList(), we would have ProjectFactory.GetProjectList() where ProjectFactory is the WS proxy and the method returns a ProjectList BO. This separates the web service part from the BO.
Hope that helps. I am interested in how you proceed. As I said, I am just delving into this approach myself.
Hi guys,
Thanks for the feedback.
Let me try and make an analogy to the ProjectTracker examples.
I'm using the PTWebService ASP.NET WebService.
My client (PTServiceClient in this case) currently calls the PTService.GetProjectList() webservice method, that returns an array of ProjectData.
What I want to do, in PTServiceClient, is to have access to the Library classes, and just call call ProjectList.GetProjectList(). This will then call the WS method, which returns the ProjectData array, which then populates the ProjectList with Projectinfo structures.
This might seem like overkill, but it gives me the options I need on the ASP.NET WebService. That is, the service can be used by other applications that don't use the Library.
Does this make sense? I could, I suppose, put some code in the ProjectList::dataPortal_Fetch to determine the context (i.e. WinForms, or WebService), and execute the WS or ADO.NET code accordingly. does that seem like a reasonable approach?
Thanks,
Sean
Sean D:
I would like to use the webservice dataportal to create, update, etc from my client, but that's not an option, as future clients will be unaware of this functionality, and will access the webservice methods directly. These will be methods like GetProject(), GetProjectList(), and will return typed data (that's described in the WSDL).
Hi guys,
Thanks for the excellent feedback. I've tried the following, and it works. But, its not the nicest of solution:
In ProjectList::DataPortal_Fetch() I do the following:
System.Web.HttpContext l_Context = System.Web.HttpContext.Current;
if (l_Context == null) // We're not in a WS or Web App
{
using (PTService.PTService svc = new PTService.PTService())
{
this.IsReadOnly = false;
foreach (ProjectData l_Project in svc.GetProjectList())
this.Add(new ProjectInfo(l_Project.Id, l_Project.Name));
this.IsReadOnly = true;
}
}
else
{
using (SqlConnection cn = new SqlConnection(Database.PTrackerConnection))
{
cn.Open();
using (SqlCommand cm = cn.CreateCommand())
.
.
Rest of existing code......
}
In the PTWebService, ProjectList.GetProjectList() is called as normal.
In the PTWin application, I call ProjectList.GetProjectList() - This now calls the PTWebService (as in the above code)...
My problem here is that a) theres a reference from the ProjectTracker.Library to the PTService, and b) if the ProjectList object is called from an ASP.NET application, it will alway call the ADO.NET directly.
This is the kinda thing I'm trying to do. I don't really want to do it this way though. Any ideas?
Many thanks,
Sean
One final thing.
I dont want to use the WebServicePortal, because I don't want objects being created and passed around the network at this time with neither Remoting nor SOAP/WS.
However, I might be changing to either .NET Remoting host, or webservice host at a later date.
Currently, CSLA.NET is configured for local dataportal only. But, as per my changes in the previous post, it calls an ASP.NET webservice (NOT the portal).
Regards,
Sean
Thanks everyone for your excellent responses. I've come to a solution to my predicament.
I am going to share my objects library between the webservice, and the client (winforms). The data access methods' implementation will be configured using a factory. The factory, configured from the config file, creates one implementation that calls the webservice methods, and the other implementation that calls the ADO.NET implementation.
Effectively, my webservice is simply an added layer of communication. I will be testing the use of the Remoting Data Portal, and WebServices data portal to see if the overhead of passing the objects round the network is minimal enough to remove my webservices comms layer.
Regards,
Sean
Copyright (c) Marimer LLC