WCF - Передача объектов, которые не объявлены как ServiceKnownType - PullRequest
0 голосов
/ 01 июня 2011

У меня есть следующий интерфейс WCF, который предоставляется через net.tcp:

[ServiceContract]
public interface IMyWCFService
{
    [OperationContract]
    Response ProcessRequest(Request request);
}

Это обусловлено следующими классами (значительно упрощенными для целей этого вопроса):

[Serializable]
public abstract class Message
{
    [XmlAttribute]
    public string Sender { get; set; }
    [XmlAttribute]
    public string Recevier { get; set; }
}

[Serializable]
public abstract class Response : Message
{
    [XmlAttribute]
    public int EventCode { get; set; }
}

[Serializable]
public abstract class Request : Message
{
    [XmlAttribute]
    public string SourceSystem { get; set; }
}

[XmlRoot(Namespace="http://blah.blah.com/blah/")]
public class StringRequest : Request
{
    [XmlElement]
    public string Payload { get; set; }
}

[XmlRoot(Namespace="http://blah.blah.com/blah/")]
public class StringResponse : Response
{
    [XmlElement]
    public string Payload { get; set; }
}

Примечание. Мы используем XMLSerializer вместо DataContractSerializer, поскольку эти классы должны быть совместимы с устаревшими системами на основе .NET 2.

Поскольку интерфейс использует абстрактные классы Запрос / Ответ в методе ProcessRequest, мы должны объявить StringResponse / StringRequest как ServiceKnownType, например:

[ServiceContract]
[ServiceKnownType(typeof(StringRequest))]
[ServiceKnownType(typeof(StringResponse))]
public interface IMyWCFService
{
    [OperationContract]
    ResponseMessage ProcessRequest(RequestMessage request);
}

Это прекрасно работает, и все хорошо в мире, однако .....

Слушатель WCF - это всего лишь один из компонентов гораздо большего фреймворка, и классы, описанные выше, используются повсеместно. Мы также разработали структуру, позволяющую нам с относительной легкостью добавлять новые типы сообщений запросов / ответов. Например, я мог бы добавить:

public class CustomRequest : Request
{
    public MyCustomXmlSerialisableRequestObject Payload { get; set; }
}

public class CustomResponse: Response
{
    public MyCustomXmlSerialisableResponseObject Payload { get; set; }
}

Что также хорошо работает, пока я не получу интерфейс службы WCF. Когда мы добавляем новую пользовательскую пару запрос / ответ, нам также необходимо обновить ServiceKnownType в интерфейсе, чтобы включить их. Что означает, что я должен повторно развернуть службу. Таким образом, вопрос - есть ли способ избежать обновления интерфейса?

В качестве примера, когда мы использовали удаленное взаимодействие, мы могли проходить через любые понравившиеся объекты, если бы они были сериализуемыми, поэтому я предполагаю / надеюсь, что в WCF есть подобное решение.

РЕДАКТИРОВАТЬ: Обновление

Следуя инструкциям, найденным здесь:

http://ashgeek.blogspot.com/2011/02/wcf-serialization-dynamically-add.html

Кажется, я на правильном пути. Однако когда я обновляю ссылку на службу клиента, она включает все динамические типы в ссылку на службу. Это нежелательно, так как не все клиенты должны или должны знать обо всех сообщениях, полученных из запроса / ответа

Что еще более важно, я, кажется, теряю класс ServiceClient, который используется для отправки сообщений, например:

// Client proxy class goes AWOL after service reference update
var client = new MyServiceReference.Client();
var responseMessage = client.ProcessRequest(requestMessage)

1 Ответ

0 голосов
/ 01 июня 2011

Вначале вы упоминаете, что вам нужна совместимость со службами .NET 2.0, но в то же время вы жалуетесь на то, что что-то, что работало в .NET remoting, не работает в WCF - вы ограничены возможностями, возможными в .NETВеб-сервисы 2.0, где и сервер, и клиент должны знать о переданных типах на уровне сервиса = типы должны быть в описании сервиса и WSDL.Более того, поскольку вы решили использовать XmlSerializer, вы обычно теряли большинство способов достижения этого:

С XmlSerializer у вас есть один вариант

  • Возврат XElement и получение XElement в вашей сервисной операции и работа с XML самостоятельно. - не работает в .NET 2.0

Редактировать:

В описании сервиса отсутствует динамическое поведение.Он создается только один раз, когда запускается хост, и после этого не меняется, пока вы не перезапустите хост.Если вам нужно подмножество WSDL для каждого клиента, вам нужна отдельная конечная точка для каждого клиента, и вы должны точно определить, какие контракты данных должны быть представлены на каждой конечной точке.

...