Interesting architectural problem
I have an application that contains two web service projects. One contains all of the "query" (read-only) functions and is publicly available to all. The other contains all of the administration (update) functions and is locked down with encryption and Windows authentication. To avoid the need for administrative users and applications to reference two separate web services, I added a project reference to the query service withinin the administration service project, and had all of the admin classes inherit and extend the query classes. This works great in 1.x, but in 2.0 websites and web services no longer compile to a single DLL, and I can't use the same architecture (VS2005 doesn't even give me the option to make a project reference to the query service).
One option I have available is to leave the web services in 1.1, but if I'm going to have to solve this problem eventually, I'd rather do it now. I'm trying to find a way to make this work in 2.0 so that I don't have to duplicate all of the query methods in the admin service. Any ideas out there?
Thanks,
Todd
[1092 byte] By [
Todd.Net] at [2008-2-10]
Well this is very interesting, cos i did the same in 1.1 just to gain extra nanoseconds, by bypassing the web services, and invoke the service in process.
The only difference for me is , there's not much login in my web service code , except acting as remote facade
example.
, the actual logic is in BusinessAction project, whic is a class library.All i culd suggest is to do lot sa refactoring, and move you business code to Domain Layer( BusinessAction). Not only you gain this benefit, but also , have the ability to expose the services through multiple channels. In our case, a plain XML(WSE) web services and TCP WSE Messaging and MSMQ easily implemented without too much of problem.
NOTE : forgive for the namespace , messup, it not my fault but they (MSDN ) had to do something about the formatting
My web services were already really just "wrappers" for the business/data layer, anyway.
I solved the problem using the following:
- I created a new class library project called WebServiceBase, and copied all of my *.asmx.cs files to that project, changed the namespace (to avoid name collisions) and compiled it. Note: I had to add a reference to System.Web.dll, which isn't added by default for class library projects
- I added a project reference from both the query and admin web services to the new WebServiceBase project.
- I modified the codebehind for all of the query web services to simply inherit from the appropriate base class in WebServiceBase (eliminating all code within the class).
- I modified the inheritance of the classes in the admin services to use the classes from WebServiceBase instead of the query web service.
While this may be a little tougher to maintain than the previous solution, I still get the original benefits without too much work. If anyone has a more "elegant" way I could have done this, I'd love to hear about it.
Cheers,
Todd Gray
Well, this solution worked fine for all web methods I already had written, but...
Whenever I add a new method to my ...Base class, then try to access that method through my admin class, I get a SOAP exception specifying that the "Server did not recognize the value of HTTP Header SOAPAction: ..." I have recompiled the project with the base classes, re-compiled the admin webservice, updated the web reference and recompiled the client. I even tried decorating my base class with [WebServiceBinding(Namespace=http://tempuri.org/)], and even that didn't work.
This is really wierd, because all of the methods I had written before conversion continue to work just fine. It's just methods that I'm adding since then. So, my solution may not be so great. Stay tuned...
Todd
Well, darn. My time to delete the previous message has expired, so now I get to look like an idiot. I was pointed at the wrong instance of my web service (the old 1.1 version running under IIS instead of the 2.0 version running in the ASP.Net dev server).

Everything works fine using my original solution. Sorry for any confusion.
Todd
I do not think this is a good approch by referencing a webservice project throught another webservcie project.
Webservcie have two ends, one is the service end, another is conumer end. by referencing the first web service project, you are turning your second web service project into the consumer of the first web services, the first project exposed. which means all the functionalities first project have is invoked through http, in your case, you are not doing webservice agregation, so, it is very costly. putting the common functionality(query db) work in a common class library project(or called business component), this can be shared easliy by both webservice project i s the better solution in my opinion.
for a relatively complicated websercie project, putting data access code directly in a webmethod is not good solution.
I'm not doing a good job of describing my architecture. There is no data access code within my web services. They are simply thin veneers over the actual data objects. What I am trying to do is to expose all of the query functions to everyone, while securing all of the admin (update) functions. This is done easily enough by splitting them into different webservice projects, one public and one secured with Windows Authentication and SSL.
Now then, I wanted to make it easier on clients consuming the admin functionality, and rather than having them add two web references, I wanted to include the query methods in the admin web services. But, I didn't want to duplicate the method code.
So, in .net 1.1, I added a reference to the DLL that was built for my query service, and had my admin service classes inherit from the query web service. For example, in my query project I have a class that looks something like this:
| | namespace Boeing { public class Airplane : System.Web.Services.WebService { [WebMethod] public DataSet GetAirplane(int SerialNo) { ... call data object ... } } } |
My admin service code looks like this:
| | namespace Boeing { public class AirplaneAdmin : Airplane { [WebMethod] public UpdateAirplane(DataSet ds) { ... Call data object ... } } } |
So, the admin service isn't calling the query service as a web service, it's simply loading the query assembly into its process space and using the functionality in the base classes.
My solution for 2.0 was to strip all of the methods out of the query service and put them in a class library project that could be shared by both the query and admin services. So, my class library project has a class in it that looks like this:
| | namespace Boeing { public class AirplaneBase : System.Web.Services.WebService { [WebMethod] public DataSet GetAirplane(int SerialNo) { ... call data object ... } } } |
My query web service project holds a reference to the class library project, and the code now looks like this:
| | namespace Boeing { public class Airplane : AirplaneBase { } } |
My admin code also holds a reference to the class library and now looks like this:
| | namespace Boeing { public class AirplaneAdmin : AirplaneBase { [WebMethod] public UpdateAirplane(DataSet ds) { ... Call data object ... } } } |
So, I'm still just loading an assembly into my process and utilizing the code. I'm not aware of a more efficient way to use code than to load the assembly into your process space, but if there is one, I'd love to hear about it.
Hopefully this explains better what I'm doing. Sorry for the confusion, guys. You mentioned Web Service aggregation, which is a term I haven't heard before. I'll have to do some research on that to see if that would work better for me.
Cheers,
Todd