#web-services #.net-3.5 #.net-2.0 #common-code
#веб-службы #.net-3.5 #.net-2.0 #общий код
Вопрос:
У меня есть веб-служба .NET 2 с единственным веб-методом, который выглядит примерно так:
[WebMethod]
public Common.foobar DoSomething(Common.foobar foo)
Класс foobar определен в общей сборке .NET 2, которая также доступна (в качестве ссылки на проект) для приложения .NET 3.5, вызывающего веб-службу через ссылку на службу (не веб-ссылку на совместимость с .NET).
Проблема в том, что пространство имен ссылок на службу содержит свою собственную, автоматически сгенерированную реализацию foobar. Таким образом, автоматически сгенерированный метод ссылки на службу, доступный в прокси-клиенте SOAP, имеет следующую подпись:
ServiceReference.foobar DoSomething(ServiceReference.foobar foo)
Небольшой поиск в Google подсказывает мне, что это неизбежно, поскольку веб-служба основана на .NET 2 и, следовательно, повторное использование общих классов не поддерживается, как в WCF.
Итак, вопрос в том, знает ли кто-нибудь простой и надежный способ клонирования общего.класс 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 service) выглядит следующим образом:
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:
На этом скриншоте видно, что конфигурация службы и, следовательно, клиентский проект осведомлены об общей библиотеке, которая содержит мою реализацию класса Foobar.
Стоит упомянуть, что все, опубликованное выше, работает, однако на самом деле класс foobar намного сложнее, чем образец, размещенный здесь. Поэтому я стремлюсь найти решение, в котором я мог бы использовать Common.foobar во всей платформе, вместо того, чтобы переводить общий.Foobar => ServiceReference.Панель инструментов для запросов и наоборот для ответов.
Комментарии:
1. Пожалуйста, попробуйте украсить свойства вашей общей библиотеки. Класс Foobar с
[DataMember]
и класс с[DataContract]
.2. Это невозможно было сделать, поскольку DataMember / DataContract были введены с WCF и .NET 3.5 — общей библиотекой является .NET 2, поскольку она используется веб-службой .NET 2. Невозможно обновить версию .NET (фактически, если бы это было возможно, я бы использовал WCF с обеих сторон и отказался от ASMX)
3. Почему бы вам просто не переместить общие классы в новую сборку и не ссылаться на нее как на стороне сервера, так и на стороне клиента? Это то, что я сделал.
Ответ №1:
Все, что я прочитал о веб-службах ASMX, предполагает, что они не поддерживают функциональность повторного использования типов на стороне клиента. Эта функциональность существует только тогда, когда служба является службой WCF, а не устаревшей службой ASMX.
Возможно, это потому, что WCF использует сериализатор различий, но я не уверен.
Возможно ли преобразовать вашу веб-службу ASMX в службу as WCF?
Комментарии:
1. Как бы мне ни хотелось, невозможно использовать WCF как фреймворк (чрезвычайно большой), который развертывается только для поддержки .NET 2.
Ответ №2:
Повторное использование классов является функцией клиентской стороны, а не серверной. Если ваш клиентский код ссылается на ту же сборку и если вы включаете общий доступ при использовании «Добавить ссылку на службу», то это может сработать.
Комментарии:
1. «это может сработать» — казалось бы, что нет — ссылка является ссылкой на службу, а не ссылкой на веб-службу совместимости .NET 2.
2. Проверено повторное использование типов в сборках, на которые даны ссылки, с выбранным параметром повторно используемые типы во всех сборках, на которые даны ссылки. Однако ссылка на службу создала собственные эквиваленты объектов, необходимых веб-службе .NET 2 ASMX
3. @MrEyes: вы уверены, что в клиентском проекте есть сборка с типами, которыми вы хотите поделиться, установленными в качестве ссылки на проект?
4. Да, чтобы протестировать это вне гораздо более крупной и сложной среды, я создал тестовое решение, которое содержит общую библиотеку .NET 2, веб-сервис .NET 2 ASMX, консольное приложение .NET 3.5, которое вызывает ASMX через ссылку на службу. Оба проекта webservice и console имеют ссылку на общую библиотеку — возникает одна и та же проблема — этот пример проекта можно найти здесь : therevcounter.com/ServiceReferenceTest.zip
5. Ссылка в предыдущем комментарии больше недоступна, я обновил исходный вопрос дополнительной информацией