1

我在将对象从客户端传输到 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 中的断点)。

请提供有关此类烦人解析器行为的线索。

提前致谢。阿列克谢·维什尼亚科夫,俄罗斯。

4

0 回答 0