views:

556

answers:

6

Say a vendor has provided two separate webservices, which both share the same data types and same namespace.

e.g. The following webservices both contain similar objects, such as a TestCredentials object:

  • TestWebservice/Testwebservice1.asmx
  • TestWebservice/Testwebservice2.asmx

Including these into Visual Studio using web references I end up with:

  • Testwebservice1.TestCredentials
  • Testwebservice2.TestCredentials

When what I really want is:

  • Testwebservice.TestCredentials

Is there any way in Visual Studio, when dealing with the web references, to link these two webservices together so that the proxy classes that are generated are the same (and within the same namespace)?

A: 

I don't believe so, at least not without tinkering with the auto-generated reference.cs code.

What comes to mind is a few workarounds: 1) create a reflection based copy method that copies values based on property names or 2) if you're using .NET 3.5, write an extension method to copy between the two types.

ZaijiaN
+1  A: 

What you should do instead of adding web references in visual studio is use the wsdl.exe command line tool to generate a proxy class that you can then edit to accept a URL instead of having two with hardcoded urls in separate namespaces.

BC
I usually do this no matter what because I hate the web references tool.
BC
Add as a web reference and not a service reference, in vs08, and its the same thing
Allen
I've been using WCF since 2008. Thanks for the info
BC
looks like the answer here is "wsdl /sharetypes"
DK
+2  A: 

Another possible option (along with wsdl.exe /sharetypes) is to use Visual Studio 2008 and use "Add Service Reference". The "Add Service Reference" dialog provides options to reuse types.

Mike Chaliy
Note that "Add Service Reference" requires that your project targets framework 3.5, while "/sharetypes" works for 2.0+.
DK
Yes of cource, at the end of the day Visual Studio will generate WCF client for ASMX web-services.
Mike Chaliy
A: 

Yes you can do that. We call it a data marshaller, but in this example I'll call it a consolidator.

You will notice that the WSDL generated class is a partial, we create a (web reference name).cs file and have something like:

Below are files you create, not WSDL generated files

WebReference1.cs


public partial class WebReferenceName1 : System.Web.Services.Protocols.SoapHttpClientProtocol 
{
    // take the methodname and append Local to the end
    public Consolidated.ReturnType MethodName1Local(params)
    {
     // redirect the return value of the call to the consolidation method and return the new value
     return Consolidation.Convert(this.MethodName1(params);
    }
}

then the second web service

WebReference2.cs


public partial class WebReferenceName2 : System.Web.Services.Protocols.SoapHttpClientProtocol 
{
    // take the methodname and append Local to the end
    public Consolidated.ReturnType MethodName2Local(params)
    {
     // redirect the return value of the call to the consolidation method and return the new value
     return Consolidation.Convert(this.MethodName2(params);
    }
}

and now the class that converts from the two types

Consolidator.cs


public class Consolidation
{
    // Input from Web Reference #1
    public static Consolidated.ReturnType Convert(WebReferenceName1.ReturnType valuetoConvert)
    {
     // Convert from valuetoConvert to Consolidated.ReturnType
     convertedValue = (conversion of valuetoConvert to Consolidated.ReturnType);

     return convertedValue;
    }

    // Input from Web Reference #2
    public static Consolidated.ReturnType Convert(WebReferenceName2.ReturnType valuetoConvert)
    {
     // Convert from valuetoConvert to Consolidated.ReturnType
     convertedValue = (conversion of valuetoConvert to Consolidated.ReturnType);

     return convertedValue;
    }
}

Basically you add methods to the web reference, call the {WebMethod}Local() methods, and that gets routed through the Consolidator and converts the simple WSDL generated class to something you can actually use.

Consolidated.ReturnType is what you define in your local project, its the local version of the data type that the WSDL generated under the web reference. Typically the "conversion" is just a clone / property by property copy from one type to another.

Allen
A: 

You can create a simple .disco file that references all the web services. It is just a simple contractRef for each web service.

Visual studio will share the types as long as they are using the same xml namespace.

eglasius
+1  A: 

You'll have to manually generate your proxy classes using the wsdl.exe program with the /sharetypes switch.

Richard Nienaber