DataContractSerializer, почему «это» не выгружается? - PullRequest
2 голосов
/ 07 февраля 2012

Я работаю на сервере с кодом F #. Этот сервер подключается к службе REST WCF с кодом C #.

Мой проект F # ссылается на сборку C #.

В моем C # у меня есть namespace GlobalNotificationService.DTO:

public class Producer
{
    [DataMember(Name = "Name", IsRequired = true, Order = 1)]
    public string Name {get; set;}
    ...
    public string Marshal()
    {
        StringBuilder sb = new StringBuilder();
        using (XmlTextWriter textWriter = new XmlTextWriter(new StringWriter(sb)))
        {
            DataContractSerializer serializer = new DataContractSerializer(typeof(DTO.Producer));                
            serializer.WriteObject(textWriter, this); //THIS IS THE LINE THROWING THE EXECPTION
            textWriter.Flush();
            textWriter.Close();
            return sb.ToString();
        }
    }
}

В моем F # у меня есть namespace ServiceCore:

type Producer(file_name) as this =
    inherit DTO.Producer()
    ...
    member public this.SerializedXML
        with get() = this.Marshal() //Call to C# assembly

Таким образом, код компилируется, но я получаю это исключение во время выполнения (см. Комментарий выше) .

Тип 'ServiceCore.Producer' с названием контракта данных 'Производитель: http://schemas.datacontract.org/2004/07/ServiceCore' нет ожидается. Рассмотрите возможность использования DataContractResolver или добавьте любые типы, не статически известен в списке известных типов - например, с помощью атрибут KnownTypeAttribute или добавив их в список известные типы передаются в DataContractSerializer.

Вопрос:

Почему "this" имеет тип ServiceCode.Producer (F #) , хотя его следует повысить до DTO.Producer (C # ) , поскольку метод находится в классе DTO.Producer , и что я явно запрашиваю сериализацию DTO.Producer ?

Дополнительный вопрос:

Почему нам даже важен тот факт, что вызов поступает из класса потомков? Наша ссылка "this" должна все же быть приведена вверх и иметь тип DTO.Producer .

Это не имеет большого смысла для меня, я что-то упустил?

Ответы [ 2 ]

4 голосов
/ 08 февраля 2012

Поскольку вы явно создаете экземпляр DCS в Marshal, вы можете изменить его определение на

public string Marshal<T>() 
...
    new DataContractSerializer(typeof<T>) ...

, а затем код F # может вызвать Marshal со своим собственным подтипом.

3 голосов
/ 07 февраля 2012

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

Для базового типа (DTO.Producer) вы должны добавить

[KnownType(typeof(ServiceCode.Producer)]

Вы также можете попытаться явно привести объект к DTO.Producer в вызове Marshal,но это может не сработать.

...