我正在使用F#编码的服务器上工作。此服务器连接到使用C#编码的WCF REST服务。
我的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的已知类型。
为什么类型为 ServiceCode.Producer (F#)的“this”,即使它应该已经上传到 DTO.Producer (C#)因为该方法位于 DTO.Producer 类中,而且我明确要求 DTO.Producer 序列化?
为什么我们甚至关心这个电话是来自后代的?我们的“此”参考仍应升级,并且类型为 DTO.Producer 。
它对我没有太大的意义,我错过了什么?
答案 0 :(得分:4)
由于您明确地在Marshal中实例化DCS,您可以将其定义更改为
public string Marshal<T>()
...
new DataContractSerializer(typeof<T>) ...
然后F#代码可以用自己的子类型调用Marshal。
答案 1 :(得分:3)
序列化中没有自动向上播种。您必须明确告诉序列化程序哪些类型与其他类型等效。
对于基本类型(DTO.Producer),您必须添加
[KnownType(typeof(ServiceCode.Producer)]
您也可以尝试在Marshal调用中将对象显式转换为DTO.Producer,但这可能不起作用。