简体   繁体   English

DataContractSerializer,为什么“ this”没有被转换?

[英]DataContractSerializer, why is “this” not upcasted?

I'm working on a server coded with F#. 我正在使用F#编码的服务器。 This server connects to a WCF REST service coded with C#. 该服务器连接到使用C#编码的WCF REST服务。

My F# project is referencing the C# assembly. 我的F#项目引用了C#程序集。

In my C# I have namespace GlobalNotificationService.DTO : 在我的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();
        }
    }
}

In my F# I have namespace ServiceCore : 在我的F#中,我有namespace ServiceCore

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

So the code does compile but I get this exception at run time (look for the comment above) . 所以代码确实可以编译,但是我在运行时遇到了这个异常(请查看上面的注释)

Type 'ServiceCore.Producer' with data contract name 'Producer:http://schemas.datacontract.org/2004/07/ServiceCore' is not expected. 不应使用数据合同名称为“ Producer:http://schemas.datacontract.org/2004/07/ServiceCore”的类型“ ServiceCore.Producer” Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer. 考虑使用DataContractResolver或将任何静态未知的类型添加到已知类型列表中 - 例如,通过使用KnownTypeAttribute属性或将它们添加到传递给DataContractSerializer的已知类型列表中。

The question is: 问题是:

Why is "this" of type ServiceCode.Producer (F#) even though it should have been upcasted to DTO.Producer (C#) since the method is in the DTO.Producer class and that I'm explicitly asking for a DTO.Producer serialization? 为什么“ this”类型为ServiceCode.Producer (F#),即使该方法应该已经转换为DTO.Producer (C#),因为该方法位于DTO.Producer类中,并且我明确要求DTO.Producer序列化?

Complementary question: 补充问题:

Why do we even care about the fact that the call is coming from a descendant class? 我们为什么还要担心调用来自后代类呢? Our "this" reference should still be up-casted and be of type DTO.Producer . 我们的“ this”引用仍应向上转换,并且应为DTO.Producer类型。

It doesn't make a lot of sence to me, am I missing something? 这对我来说意义不大,我想念什么吗?

Since you're explicitly instantiating the DCS in Marshal, you could change its definition to to be 由于您要在元帅中明确实例化DCS,因此可以将其定义更改为

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

and then the F# code could call Marshal with its own subtype. 然后F#代码可以使用自己的子类型调用元帅。

There is no automatic upcast in serialization. 序列化中没有自动转换。 You have to tell the serializer explicitly what types are equivalent to other types. 您必须明确告诉序列化器哪些类型与其他类型等效。

For the base type (DTO.Producer) you have to add a 对于基本类型(DTO.Producer),您必须添加一个

[KnownType(typeof(ServiceCode.Producer)]

You might also be able to try and explicitly cast the object to DTO.Producer in the Marshal call, but that might not work. 您也可以尝试在Marshal调用中将对象显式转换为DTO.Producer,但这可能无法正常工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM