Веб-служба .NET 2 ASMX - вызывается через справочник по .NET 3.5 - повторное использование классов - PullRequest
1 голос
/ 18 мая 2011

У меня есть веб-сервис .NET 2 с одним веб-методом, который выглядит примерно так:

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

Класс foobar определен в общей сборке .NET 2, которая также доступна (в качестве ссылки на проект) для приложения .NET 3.5, которое вызывает веб-сервис через ссылку на службу (не веб-ссылку на совместимость .NET).

Проблема в том, что пространство имен справочной службы содержит собственную, автоматически сгенерированную реализацию foobar. Таким образом, автоматически сгенерированный метод Service Reference, доступный на прокси-клиенте SOAP, имеет следующую подпись:

ServiceReference.foobar DoSomething(ServiceReference.foobar foo)

Немного погуглив, скажите, что это неизбежно, поскольку веб-служба основана на .NET 2, и поэтому повторное использование общих классов не поддерживается, как в WCF.

Итак, вопрос: кто-нибудь знает простой и надежный способ клонирования класса Common.foobar в класс WebServiceReference.foobar? В качестве альтернативы кто-нибудь знает "хак", где я могу использовать класс, как определено в общей библиотеке? В качестве альтернативы кто-нибудь может указать, где я пропустил лес за деревьями, и на самом деле можно использовать класс общей библиотеки

РЕДАКТИРОВАТЬ - Дополнительная информация

Класс веб-службы .NET 2 выглядит следующим образом:

[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" };
    }
}

Вызывающий клиент (.NET 3.5 - со ссылкой на службу .NET) выглядит следующим образом:

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);
}

Класс foobar в общей библиотеке (также .NET 2) выглядит следующим образом:

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;
        }
    }
}

И получен из схемы, которая выглядит следующим образом:

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

И, наконец, вот скриншот страницы конфигурации справочника услуг на клиенте .NET 3.5:

Screen shot of .NET 3.5 Service Config page

Из этого снимка экрана видно, что Конфигурация службы и, следовательно, клиентский проект, знают о CommonLibrary, в которой содержится моя реализация класса Foobar.

Стоит отметить, что все вышеперечисленное работает, однако в действительности класс foobar намного сложнее, чем пример, размещенный здесь. Поэтому я стремлюсь найти решение, в котором я могу использовать Common.foobar во всей структуре вместо того, чтобы переводить Common.Foobar => ServiceReference.Foobar для запросов и наоборот для ответов.

Ответы [ 2 ]

1 голос
/ 07 сентября 2011

Все, что я читал о веб-сервисах ASMX, говорит о том, что они не поддерживают функциональность повторного использования типов на стороне клиента.Эта функциональность существует только тогда, когда служба является службой WCF, а не устаревшей службой ASMX.

Возможно, это потому, что WCF использует разностный сериализатор, но я не уверен.

Возможно ли преобразовать ваш веб-сервис ASMX в службу WCF?

0 голосов
/ 18 мая 2011

Повторное использование классов является функцией на стороне клиента, а не на стороне сервера. Если ваш клиентский код ссылается на одну и ту же сборку и если вы используете общий доступ при использовании «Добавить ссылку на службу», это может сработать.

...