Веб-служба.NET 2 ASMX - вызывается через справочник по.NET 3.5 - повторное использование классов
У меня есть веб-сервис.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:
Из этого снимка экрана видно, что Конфигурация службы и, следовательно, клиентский проект знают о CommonLibrary, в которой содержится моя реализация класса Foobar.
Стоит отметить, что все вышеперечисленное работает, однако в действительности класс foobar намного сложнее, чем образец, размещенный здесь. Поэтому я стремлюсь найти решение, в котором я могу использовать Common.foobar во всей структуре, вместо того, чтобы переводить Common.Foobar => ServiceReference.Foobar для запросов и наоборот для ответов.
2 ответа
Все, что я читал о веб-сервисах ASMX, говорит о том, что они не поддерживают функциональность повторного использования типов на стороне клиента. Эта функциональность существует только тогда, когда служба является службой WCF, а не устаревшей службой ASMX.
Возможно, это потому, что WCF использует сериализатор различий, но я не уверен.
Можно ли конвертировать ваш веб-сервис ASMX в сервис WCF?
Повторное использование классов является функцией на стороне клиента, а не на стороне сервера. Если ваш клиентский код ссылается на ту же сборку, и если вы включаете общий доступ при использовании "Добавить ссылку на службу", то это может сработать.