将DataContractSurrogate与WCF REST一起使用

时间:2011-01-20 00:12:49

标签: .net wcf datacontractserializer datacontract

如何为我的WCF REST服务使用DataContractSurrogate(使用WebServiceHostFactory托管)?

我没有看到添加一个的方法,即使我添加了自定义IOperationBehavior,WebServiceHost也会自动覆盖并忽略它。

2 个答案:

答案 0 :(得分:5)

您可以通过以下两个步骤实现此目的:

首先,实现IDatacontractSurrogate接口:

class MySurrogate : IDataContractSurrogate
{

    public Type GetDataContractType(Type type)
    {
        //Implementation here
    }

    public object GetObjectToSerialize(object obj, Type targetType)
    {
        //Implementation here
    }

    //Implemenentation of the remaining methods...
}

其次,在ServiceHost上设置您的代理人:

foreach (var endpoint in serviceHost.Description.Endpoints)
{
    foreach (var operation in endpoint.Contract.Operations)
    {
         operation.Behaviors.Find<DataContractSerializerOperationBehavior>().DataContractSurrogate = new MySurrogate();
    }
}

请务必在打开服务主机之前执行此操作。否则可能无效。

如果您正在使用IIS主机并在WebServiceHostFactory文件中指定.svc,那么可以理解的是,您没有机会设置代理。要克服这个问题,您有两种选择:

  1. 创建自定义服务行为属性并在其ApplyDispatchBehavior()方法中设置代理项。将此属性放在服务上后,WCF将自动执行此方法并设置代理项。

  2. 通过继承WebServiceHost
  3. Create您自己的自定义服务主机。然后在其ApplyConfiguration()方法中设置代理项。这也会产生同样的效果。

答案 1 :(得分:3)

我设法让它工作:使用IIS中的WebServiceHostFactory托管WCF 4.0 REST服务。

我使用自定义属性来注入我的NHProxyDataContractSurrogate:

public class CanSerializeNHProxyAttribute : Attribute, IContractBehavior
{
    public void ApplyClientBehavior(ContractDescription description, ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime proxy)
    {
        foreach (OperationDescription opDesc in description.Operations)
        {
            ApplyDataContractSurrogate(opDesc);
        }
    }

    public void ApplyDispatchBehavior(ContractDescription description, ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.DispatchRuntime dispatch)
    {
        foreach (OperationDescription opDesc in description.Operations)
        {
            ApplyDataContractSurrogate(opDesc);
        }
    }

    private static void ApplyDataContractSurrogate(OperationDescription description)
    {
        DataContractSerializerOperationBehavior dcsOperationBehavior = description.Behaviors.Find<DataContractSerializerOperationBehavior>();
        if (dcsOperationBehavior != null)
        {
            if (dcsOperationBehavior.DataContractSurrogate == null)
                dcsOperationBehavior.DataContractSurrogate = new NHProxyDataContractSurrogate();
        }
    }

    public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint serviceEndPoint, BindingParameterCollection parameters) { }

    public void Validate(ContractDescription contractDescription, ServiceEndpoint serviceEndPoint) { }
}

并将自定义属性应用于我的ServiceContract:

[ServiceContract]
[CanSerializeNHProxy]
public interface IElementManager
{ ... }

我从这些链接中获得了很多有用的信息:

DataContractSurrogate MSDN page, pointing to custom attribute

DataContractSurrogate implementation for serializing NHibernate proxy objects

希望这有帮助。