将 DataContractSurrogate 与 WCF REST 结合使用

发布于 2024-10-12 21:21:17 字数 155 浏览 4 评论 0原文

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

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

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

原谅我要高飞 2024-10-19 21:21:17

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

首先,实现 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. 通过子类化 WebServiceHost 创建您自己的自定义服务主机。然后在其 ApplyConfiguration() 方法中设置代理。这也将具有相同的效果。

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.

溇涏 2024-10-19 21:21:17

我设法让它工作:使用 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 页面,指向自定义属性

用于序列化 NHibernate 代理对象的 DataContractSurrogate 实现

希望这会有所帮助。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文