Использование DataContractSurrogate с WCF REST - PullRequest
1 голос
/ 20 января 2011

Как я могу использовать DataContractSurrogate для моей службы WCF REST (размещенной с использованием WebServiceHostFactory)?

Я не вижу способа добавить его, и даже если я добавлю пользовательский IOperationBehavior, WebServiceHost автоматически перезаписывает и игнорирует его.

Ответы [ 2 ]

5 голосов
/ 31 июля 2011

Это можно сделать с помощью следующих двух шагов:

Во-первых, реализовать интерфейс 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.Затем установите суррогат в методе ApplyConfiguration().Это тоже будет иметь тот же эффект.

3 голосов
/ 07 февраля 2013

Мне удалось заставить его работать: служба REST WCF 4.0, размещенная с использованием WebServiceHostFactory в IIS.

Я использовал пользовательский атрибут для внедрения моего 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, указывающая на пользовательский атрибут

Реализация DataContractSurrogate для сериализации прокси-объектов NHibernate

Надеюсь, это поможет.

...