张贴后我还发现这个SO相同的问题How to serialize a derived type as base。 marc对我的未被接受的第二个答案是解决这个问题的最简单的方法。那就是:
装饰派生类与[DataContract(Name="BaseClass")]
请注意,此解决方案意味着衍生将作为基础运输该对象的传输的所有每一种情况下。对于我来说,如果它不是问题,那么你需要去DataContractResolver路由。
的DataContractResolver路线上的一些注意事项:
1.这使您可以通过导出一些呼叫衍生而来,但作为基础的其他 - 如果你需要做到这一点 - 如果不是名称=方式使用。
2.我从datacontractrsolver文章中使用DeserializeAsBaseResolver得到一个异常,因为knownTypeResolver返回false。为了解决这个问题,我忽略了该调用的返回值,并始终从TryResolveType返回true。这似乎工作。 3 3。我最初认为,因为我们序列化为基础,我并不需要派生类上的[DataContract]。那是错误的。该对象被序列化为派生对象并作为基础对象进行derserialized - 因此您必须用[DataContract]修饰派生,但不要将任何字段标记为[DataMembers]以避免它们被不必要地序列化。
4.如果您有命令行主机和服务主机,则需要代码在两者中插入合约解析器。我发现将它作为静态解析器很有用。
5.请注意,cd.Operations.Find("Get_gateway_data")
调用中的“Get_gateway_data”字符串是返回相关对象的合同方法的名称。您需要为每个需要此行为的呼叫执行此操作。
这种方法最终代码:
public class DeserializeAsBaseResolver : DataContractResolver {
public static void Install(ServiceHost service_host) {
// Setup DataContractResolver for GatewayProcessing to GatewayData resolution:
ContractDescription cd = service_host.Description.Endpoints[0].Contract;
OperationDescription myOperationDescription = cd.Operations.Find("Get_gateway_data");
DataContractSerializerOperationBehavior serializerBehavior = myOperationDescription.Behaviors.Find<DataContractSerializerOperationBehavior>();
if (serializerBehavior == null) {
serializerBehavior = new DataContractSerializerOperationBehavior(myOperationDescription);
myOperationDescription.Behaviors.Add(serializerBehavior);
}
serializerBehavior.DataContractResolver = new DeserializeAsBaseResolver();
}
public override bool TryResolveType(Type type, Type declaredType,
DataContractResolver knownTypeResolver,
out XmlDictionaryString typeName,
out XmlDictionaryString typeNamespace) {
bool ret = knownTypeResolver.TryResolveType(type, declaredType, null, out typeName, out typeNamespace);
//return ret; // ret = false which causes an exception.
return true;
}
public override Type ResolveName(string typeName, string typeNamespace,
Type declaredType, DataContractResolver knownTypeResolver) {
return knownTypeResolver.ResolveName(typeName, typeNamespace, declaredType, null) ?? declaredType;
}
主机代码(服务或命令行):
using (ServiceHost service_host = new ServiceHost(typeof(GatewayServer))) {
// Setup DataContractResolver for GatewayProcessing to GatewayData resolution:
DeserializeAsBaseResolver.Install(service_host);
// Open the host and start listening for incoming messages.
try { service_host.Open(); }
我已经改变了接受下面,因为我想强调的名称我自己的答案= “BaseClass”评价,这是我真正想要的。感谢您的输入。 KnownType的+1将无法解析。 – Ricibob