你可以解决这个问题
使用DataContractSurrogate进行反序列化,该反序列化将IList替换为List。
public class CustomDataContractSurrogate : IDataContractSurrogate
{
// The only function you should care about here. The rest don't do anything, just default behavior.
public Type GetDataContractType(Type type)
{
if (type.IsGenericType && type.GetGenericTypeDefinition().Equals(typeof(ICollection<>)))
{
return (typeof(List<>).MakeGenericType(type.GetGenericArguments().Single()));
}
return type;
}
public object GetObjectToSerialize(object obj, Type targetType)
{
return obj;
}
public object GetDeserializedObject(object obj, Type targetType)
{
return obj;
}
public object GetCustomDataToExport(MemberInfo memberInfo, Type dataContractType)
{
return null;
}
public object GetCustomDataToExport(Type clrType, Type dataContractType)
{
return null;
}
public void GetKnownCustomDataTypes(Collection<Type> customDataTypes)
{
}
public Type GetReferencedTypeOnImport(string typeName, string typeNamespace, object customData)
{
return null;
}
public CodeTypeDeclaration ProcessImportedType(CodeTypeDeclaration typeDeclaration, CodeCompileUnit compileUnit)
{
return typeDeclaration;
}
}
基本上就是这样,您只需使用该代理项创建DataContractSerializer实例,并将其用于反序列化(对于序列化来说,这并不重要),例如:
var serializer = new DataContractSerializer(type, new Type[]{}, Int32.MaxValue, false, true, new CustomDataContractSurrogate());
或者采用代理的任何其他构造函数。
或
,(作为答案的补充)如果您使用app/web.config定义的服务,则可以定义自定义行为,该行为使用上述代理创建数据协定序列化程序:
public class CustomDataContractSerializerBehavior : DataContractSerializerOperationBehavior
{
public CustomDataContractSerializerBehavior(OperationDescription operation)
: base(operation)
{
}
public CustomDataContractSerializerBehavior(OperationDescription operation, DataContractFormatAttribute dataContractFormatAttribute)
: base(operation, dataContractFormatAttribute)
{
}
public override XmlObjectSerializer CreateSerializer(Type type, string name, string ns,
IList<Type> knownTypes)
{
return new DataContractSerializer(type, knownTypes, Int32.MaxValue, false, true, new CustomDataContractSurrogate());
}
public override XmlObjectSerializer CreateSerializer(Type type, XmlDictionaryString name,
XmlDictionaryString ns, IList<Type> knownTypes)
{
return new DataContractSerializer(type, knownTypes, Int32.MaxValue, false, true, new CustomDataContractSurrogate());
}
}
终于
您可以使用此行为:
public static IMyDataServiceContract CreateService()
{
var factory = new ChannelFactory<IMyDataServiceContract>("MyServiceName");
SetDataContractSerializerBehavior(factory.Endpoint.Contract);
return factory.CreateChannel();
}
private static void SetDataContractSerializerBehavior(ContractDescription contractDescription)
{
foreach (OperationDescription operation in contractDescription.Operations)
{
ReplaceDataContractSerializerOperationBehavior(operation);
}
}
private static void ReplaceDataContractSerializerOperationBehavior(OperationDescription description)
{
DataContractSerializerOperationBehavior dcsOperationBehavior =
description.Behaviors.Find<DataContractSerializerOperationBehavior>();
if (dcsOperationBehavior != null)
{
description.Behaviors.Remove(dcsOperationBehavior);
description.Behaviors.Add(new CustomDataContractSerializerBehavior(description));
}
}
完成这项工作
,调用上面的CreateService来创建通道。