Using a DataContractSurrogate with WCF REST

五迷三道 提交于 2019-12-01 11:49:23

问题


How can I use a DataContractSurrogate for my WCF REST service (hosted using a WebServiceHostFactory)?

I don't see a way of adding one and even if I add a custom IOperationBehavior, the WebServiceHost automatically overwrites and ignores it.


回答1:


You can achieve this with the following two steps:

First, implement IDatacontractSurrogate interface:

class MySurrogate : IDataContractSurrogate
{

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

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

    //Implemenentation of the remaining methods...
}

Second, set your surrogate on the ServiceHost like this:

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

Remember to do this before you open your service host. Otherwise it may not work.

In case you're using IIS hosting and specifying the WebServiceHostFactory in an .svc file, then understandably, you don't have the opportunity set the surrogate. To overcome that, you have two options:

  1. Create a custom service behavior attribute and set the surrogate in its ApplyDispatchBehavior() method. Once you place this attribute on your sevice, WCF will automatically execute this method and the surrogate will be set.

  2. Create your own custom service host by subclassing WebServiceHost. Then set the surrogate in its ApplyConfiguration() method. This too will have the same effect.




回答2:


I managed to get it working: WCF 4.0 REST service hosted using a WebServiceHostFactory in IIS.

I used a custom attribute to inject my 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) { }
}

And applied the custom attribute to my ServiceContract:

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

I got a lot of useful info from these links:

DataContractSurrogate MSDN page, pointing to custom attribute

DataContractSurrogate implementation for serializing NHibernate proxy objects

Hope this helps.



来源:https://stackoverflow.com/questions/4742225/using-a-datacontractsurrogate-with-wcf-rest

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!