我在将对象从客户端传输到 WCF 服务时遇到问题。我不能使用标准合同定义,因为它是几个不同应用程序的通用服务。
服务器和客户端都有一个定义了传输类型的程序集,因此服务器可以从 SOAP 消息中反序列化对象实例。首先,我尝试“按原样”发送此对象,但收到有关非预期合同名称的消息:“不应使用数据合同名称‘X:Y’键入‘类型名称’。考虑使用 DataContractResolver 或添加任何未知类型静态添加到已知类型列表中 - 例如,通过使用 KnownTypeAttribute 属性或将它们添加到传递给 DataContractSerializer 的已知类型列表中。”
经过研究,我了解到有几种方法可以解决这个问题:1.使用 KnownType[] 属性(这是不可能的,因为我不知道编译时所有类型) 2.使用静态合约(类似) 3. 使用 DataContractResolver (没关系,因为我可以查看程序集并尝试找到这些类型)
在学习了这篇文章之后 - http://code.msdn.microsoft.com/windowsdesktop/WCF-Data-Contract-Resolver-7de9b8b4#content - 我在我的项目中创建了一个替换解析器的属性(因为它是 IIS 托管的):
public class DataContractResolverAttribute: Attribute, IOperationBehavior
{
private Type _resolverType = null;
public DataContractResolverAttribute (Type resolver)
{
_resolverType = resolver;
}
public void AddBindingParameters (OperationDescription description, BindingParameterCollection parameters)
{
}
public void ApplyClientBehavior (OperationDescription description, ClientOperation proxy)
{
AddResolverToOperation(description);
}
public void ApplyDispatchBehavior (OperationDescription description, DispatchOperation dispatch)
{
AddResolverToOperation(description);
}
public void Validate (OperationDescription description)
{
}
private void AddResolverToOperation (OperationDescription description)
{
DataContractSerializerOperationBehavior dcs = description.Behaviors.Find<DataContractSerializerOperationBehavior>();
if (dcs != null)
{
dcs.DataContractResolver = Activator.CreateInstance(_resolverType) as DataContractResolver;
}
}
}
另外,我已将此属性分配给操作:
[OperationContract]
[FaultContract(typeof(string))]
[DataContractResolver(typeof(CustomResolver))]
RuleResultData ExecuteRuleObj (object context, int ruleId);
CustomResolver 是 DataContractResolver 的后代:
class CustomResolver: DataContractResolver
{
public override Type ResolveName (string typeName, string typeNamespace, Type declaredType, DataContractResolver knownTypeResolver)
{
// ... not significant here ...
}
public override bool TryResolveType (Type type, Type declaredType, DataContractResolver knownTypeResolver, out XmlDictionaryString typeName, out XmlDictionaryString typeNamespace)
{
// ... not significant here ...
}
}
在调试时,我看到 Resolver 已成功替换(在 AddResolverToOperation 中设置断点),但在调用时我看不到任何效果(未触发 ResolveName 和 TryResolveType 中的断点)。
请提供有关此类烦人解析器行为的线索。
提前致谢。阿列克谢·维什尼亚科夫,俄罗斯。