Using DataContractSurrogate with WCF REST

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

I see no way to add it, and even if I add a custom IOperationBehavior, WebServiceHost will automatically overwrite and ignore it.

+1
source share
2 answers

This can be done using the following two steps:

First we implement the 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... } 

Secondly, set the surrogate to ServiceHost as follows:

 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 opening the host server. Otherwise, this may not work.

If you use IIS hosting and specify WebServiceHostFactory in the .svc file, then, of course, you have no way to install a surrogate. To overcome this, you have two options:

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

  • Create your own custom service host by subclassing WebServiceHost . Then set the surrogate to the ApplyConfiguration() method. This will also have the same effect.

+5
source

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

I used a custom attribute to input 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 a custom attribute to my ServiceContract:

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

I got a lot of useful information on these links:

MSDN DataContractSurrogate Page Pointing to a Custom Attribute

Implementing a DataContractSurrogate to Serialize NHibernate Proxy Objects

Hope this helps.

+3
source

Source: https://habr.com/ru/post/953224/


All Articles