【问题标题】:Using a DataContractSurrogate with WCF REST将 DataContractSurrogate 与 WCF REST 一起使用
【发布时间】:2011-01-20 00:12:48
【问题描述】:

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

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

【问题讨论】:

    标签: .net wcf datacontractserializer datacontract


    【解决方案1】:

    您可以通过以下两个步骤来实现:

    首先,实现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 托管并在 .svc 文件中指定 WebServiceHostFactory,那么可以理解,您没有机会设置代理项。为了克服这个问题,您有两种选择:

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

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

    【讨论】:

    • WebServiceHost 不会在您应用自定义 DataContractSerializerOperationBehavior 时监听它。它会忽略并覆盖它。
    • 这很奇怪。我上面描述的方式在我的情况下非常有效。您确定 Jeff 在打开主机之前设置代理吗?
    • 嗯,我一定会再试一次...但我认为这是一个已知问题...谢谢。
    【解决方案2】:

    我设法让它工作:使用 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

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 2013-06-08
      • 1970-01-01
      • 2011-03-26
      • 1970-01-01
      • 2013-11-06
      • 1970-01-01
      • 2014-03-16
      • 2011-02-04
      相关资源
      最近更新 更多