張貼後我還發現這個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