1

I have a .NET 2 web service with a single web method that looks something like this:

[WebMethod]
public Common.foobar DoSomething(Common.foobar foo)

The foobar class is defined in a common .NET 2 assembly that is also available (as a project reference) to a .NET 3.5 application that calls the webservice via a Service Reference (not a .NET compatibility web reference).

The issue is that the service reference namespace contains its own, auto generated, implementation of foobar. So the auto generated Service Reference method, available on the proxy SOAP client, has the following signature:

ServiceReference.foobar DoSomething(ServiceReference.foobar foo)

A little googling tell me that this is unavoidable as the web service is .NET 2 based and therefore reuse of common classes is not supported as it is in WCF.

So the question is: does anybody know of a simple and reliable way to clone a Common.foobar class into a WebServiceReference.foobar class? Alternatively does anybody know of a "hack" where I can use the class as defined in the Common library? Alternatively can anybody point out where I have missed the wood for the trees and it is infact possible to use the Common library class

EDIT - Some more information

The .NET 2 webservice class looks like this:

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
public class Service1 : System.Web.Services.WebService
{
    [WebMethod]
    public CommonLibrary.Foobar DoSomething(CommonLibrary.Foobar foo)
    {
        return new CommonLibrary.Foobar() { Data = "Data in common foobar class", EventCode = 1, MessageId = "mid" };
    }
}

The invoking client (.NET 3.5 - With a Service Reference to the .NET service) looks like this:

static void Main(string[] args)
{
    // Create the soap client for the .NET 2 service using the auto generated proxy class
    var serviceClient = new NET2WebService_ServiceReference.Service1SoapClient();

    //Just checking that there is a project reference to CommonLibrary
    var commonFoobar_Request = new CommonLibrary.Foobar()
    {
        Data = "Common foobar data",
        EventCode = 1,
        MessageId = "Common foobar message id"
    };

    // This doesn't work as the Service Reference client does not accept the
    // common foobar class.
    /*
    var commonFoobar_Response = serviceClient.DoSomething(commonFoobar_Request);
    Console.WriteLine(commonFoobar_Response.Data);
    */

    // This is the proxy class to foobar generated by the Service Reference
    var serviceRefFoobar_Request = new NET2WebService_ServiceReference.Foobar()
    {
        Data = "Common foobar data",
        EventCode = 1,
        MessageId = "Common foobar message id"
    };

    // This does work as it does uses the autogenerated Foobar class in the service
    // reference
    var serviceRefFoobar_Response = serviceClient.DoSomething(serviceRefFoobar_Request);
    Console.WriteLine(serviceRefFoobar_Response.Data);
}

The foobar class in the common library (also .NET 2) looks like this:

public partial class Foobar
{
    private string dataField;
    private int eventCodeField;
    private string messageIdField;

    public string Data
    {
        get
        {
            return this.dataField;
        }
        set
        {
            this.dataField = value;
        }
    }

    public int EventCode
    {
        get
        {
            return this.eventCodeField;
        }
        set
        {
            this.eventCodeField = value;
        }
    }

    public string MessageId
    {
        get
        {
            return this.messageIdField;
        }
        set
        {
            this.messageIdField = value;
        }
    }
}

And is derived from a schema that looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
    <xs:element name="Foobar">
        <xs:annotation>
            <xs:documentation>Comment describing your root element</xs:documentation>
        </xs:annotation>
        <xs:complexType>
            <xs:sequence>
                <xs:element name="Data" type="xs:string"/>
                <xs:element name="EventCode" type="xs:int"/>
            </xs:sequence>
            <xs:attribute name="MessageId" type="xs:string" use="required"/>
        </xs:complexType>
    </xs:element>
</xs:schema>

And finally, here is a screenshot of the Service Reference configuration page on the .NET 3.5 client:

Screen shot of .NET 3.5 Service Config page

You can see from that screenshot that the Service Configuration, and therefore the client project, is aware of the CommonLibrary that contains my implementation of the Foobar class.

It is worth mentioning that everything posted above works, however in reality the foobar class is far more complicated that the sample posted here. Therefore I am keen to find a solution where I can use Common.foobar throughout the entire framework rather than having to translate Common.Foobar => ServiceReference.Foobar for requests and vice versa for responses.

MrEyes
  • 13,059
  • 10
  • 48
  • 68
  • Please try decorating the properties of your CommonLibrary.Foobar class with `[DataMember]` and the class with `[DataContract]`. – John Saunders May 19 '11 at 15:23
  • That can't been done as DataMember/DataContract were introduced with WCF and .NET 3.5 - the common library is .NET 2 as it is used by the .NET 2 Web Service. It isn't feasible to upgrade the version of .NET (in fact if this was a possibility I would use WCF on both sides and abandon the ASMX) – MrEyes May 19 '11 at 18:27
  • Why don't you just move the shared classes into a new assembly and reference it on both the server and client side? That's what I did. – ashes999 Feb 08 '12 at 15:19

2 Answers2

1

Everything I have read about ASMX web services suggests that they do not support the functionality of reusing types on the client side. This functionality only exists when the service is a WCF service and not a legacy ASMX service.

Perhaps it’s because WCF uses a difference serializer, but I’m not sure.

Is it possible to convert your ASMX web service to as WCF service?

ChrisNel52
  • 14,655
  • 3
  • 30
  • 36
  • As much as I would like to it isn't possible to WCF as the framework (extremely large) that this is being deployed to only support .NET 2. – MrEyes Sep 08 '11 at 12:55
0

The reuse of classes is a function of the client side, not the server side. If your client code references the same assembly, and if you enable sharing when you use "Add Service Reference", then this may work.

John Saunders
  • 160,644
  • 26
  • 247
  • 397
  • "this may work" - it would seem that not - the reference is a service reference rather than a .NET 2 compatibility web service reference. – MrEyes May 18 '11 at 20:05
  • Reuse types in referenced assemblies is checked, with the reused types in all referenced assembles option selected. However the Service Reference has generated its own equivalents of the objects the .NET 2 ASMX web service requires – MrEyes May 18 '11 at 22:44
  • @MrEyes: are you sure the client project has the assembly with the types you want to share set as a project reference? – John Saunders May 18 '11 at 22:52
  • Yes, to test this outside the much larger and more complex framework I have created a test solution that contains a .NET 2 common library, .NET 2 ASMX webservice, .NET 3.5 console app that invokes the ASMX via a Service Reference. Both the webservice and console projects have a reference to common library - the same issue occurs - this sample project can be found here : http://www.therevcounter.com/ServiceReferenceTest.zip – MrEyes May 18 '11 at 23:21
  • The link in the previous comment is no longer available, I have updated the original question with further information – MrEyes May 19 '11 at 09:28