在WCF服务中发送对象的实例

时间:2012-07-04 07:26:49

标签: c# wcf datacontract

我从客户端将对象传输到WCF服务时遇到问题。我无法使用标准合约定义,因为它是几个不同应用程序的通用服务。

服务器和客户端都有一个程序集,其中定义了传输类型,因此服务器可以从SOAP消息反序列化对象实例。首先,我尝试“按原样”发送此对象,但得到了关于未预期的合同名称的消息:“类型'类型名称'与数据合同名称'X:Y'不是预期的。考虑使用DataContractResolver或添加任何未知的类型静态地到已知类型的列表 - 例如,通过使用KnownTypeAttribute属性或将它们添加到传递给DataContractSerializer的已知类型列表。“

经过研究,我了解到有几种方法可以解决这个问题: 1.使用KnownType []属性(这是不可能的,因为我不知道编译时所有类型) 2.使用静态合约(类似) 3.使用DataContractResolver(没关系,因为我可以查看程序集并尝试查找这些类型)

在学习本文之后 - http://code.msdn.microsoft.com/windowsdesktop/WCF-Data-Contract-Resolver-7de9b8b4#content - 我创建了一个属性来替换我的项目中的Resolver(因为它是由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中的断点都没有被触发)。

请提供关于这种令人讨厌的解析器行为的线索。

提前致谢。 Alexey Vishnyakov,俄罗斯。

0 个答案:

没有答案