Using a DataContractSurrogate with WCF REST
Asked Answered
M

2

1

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.

Maiduguri answered 20/1, 2011 at 0:12 Comment(0)
R
5

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.

Radioactivity answered 31/7, 2011 at 5:25 Comment(3)
WebServiceHost doesn't listen to a custom DataContractSerializerOperationBehavior if you apply it. It ignores and overwrites it.Maiduguri
That's odd. The way I described above works perfectly in my case. Are you sure Jeff that you're setting the surrogate before the host is opened?Radioactivity
Hmmm, I'll certainly try it again...but I think this is a known issue... Thanks.Maiduguri
E
3

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.

Exploiter answered 7/2, 2013 at 17:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.