You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

迁移WCF至.NET Standard 2.0:DataContractSerializerOperationBehavior代理配置问题

解决方案:在.NET Standard 2.0中为DataContractSerializerOperationBehavior注入自定义Surrogate

我之前在迁移WCF代码到.NET Standard 2.0并使用System.ServiceModel.Primitives 4.5.0-preview1版本时,也碰到了一模一样的问题——原来的DataContractSerializerOperationBehavior.DataContractSurrogate属性确实被移除了。不过通过自定义操作行为替换序列化器工厂的方式,完全可以实现注入自定义ISerializationSurrogateProvider的需求,下面是具体的实现步骤:

1. 创建自定义操作行为和序列化器工厂

我们需要实现一个IOperationBehavior,用来替换默认的DataContractSerializerFactory,让它在创建DataContractSerializer时带上我们的代理类:

// 自定义操作行为,用于注入Surrogate
public class SurrogateOperationBehavior : IOperationBehavior
{
    private readonly ISerializationSurrogateProvider _surrogate;

    public SurrogateOperationBehavior(ISerializationSurrogateProvider surrogate)
    {
        _surrogate = surrogate;
    }

    public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters)
    {
        // 无需额外处理
    }

    public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)
    {
        ReplaceDefaultSerializer(operationDescription);
    }

    public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
    {
        ReplaceDefaultSerializer(operationDescription);
    }

    public void Validate(OperationDescription operationDescription)
    {
        // 无需额外处理
    }

    private void ReplaceDefaultSerializer(OperationDescription operationDescription)
    {
        // 找到当前操作上的DataContractSerializerOperationBehavior
        var dcsBehavior = operationDescription.Behaviors.Find<DataContractSerializerOperationBehavior>();
        if (dcsBehavior != null)
        {
            // 替换为我们自定义的序列化器工厂
            dcsBehavior.SerializerFactory = new SurrogateSerializerFactory(_surrogate);
        }
    }
}

// 自定义序列化器工厂,创建带有Surrogate的DataContractSerializer
public class SurrogateSerializerFactory : DataContractSerializerFactory
{
    private readonly ISerializationSurrogateProvider _surrogate;

    public SurrogateSerializerFactory(ISerializationSurrogateProvider surrogate)
    {
        _surrogate = surrogate;
    }

    public override XmlObjectSerializer CreateSerializer(Type type, string name, string ns, IList<Type> knownTypes)
    {
        var settings = new DataContractSerializerSettings
        {
            DataContractSurrogate = _surrogate,
            KnownTypes = knownTypes
        };
        return new DataContractSerializer(type, name, ns, settings);
    }

    public override XmlObjectSerializer CreateSerializer(Type type, XmlDictionaryString name, XmlDictionaryString ns, IList<Type> knownTypes)
    {
        var settings = new DataContractSerializerSettings
        {
            DataContractSurrogate = _surrogate,
            KnownTypes = knownTypes
        };
        return new DataContractSerializer(type, name, ns, settings);
    }
}

2. 将自定义行为添加到服务或客户端

服务端配置

在创建ServiceHost后,遍历所有端点和操作,添加我们的自定义行为:

var serviceHost = new ServiceHost(typeof(MyService));
// 遍历所有端点
foreach (var endpoint in serviceHost.Description.Endpoints)
{
    // 遍历端点下的所有操作
    foreach (var operation in endpoint.Contract.Operations)
    {
        operation.Behaviors.Add(new SurrogateOperationBehavior(new MyDataContractSurrogate()));
    }
}
serviceHost.Open();

客户端配置

在创建ChannelFactory后,同样遍历操作添加行为:

var binding = new BasicHttpBinding();
var endpointAddress = new EndpointAddress("http://localhost/MyService");
var factory = new ChannelFactory<IMyService>(binding, endpointAddress);

foreach (var operation in factory.Endpoint.Contract.Operations)
{
    operation.Behaviors.Add(new SurrogateOperationBehavior(new MyDataContractSurrogate()));
}

var channel = factory.CreateChannel();
// 开始使用channel调用服务

关键说明

  • 核心思路是替换默认的SerializerFactory,让它在实例化DataContractSerializer时,通过DataContractSerializerSettings注入你的MyDataContractSurrogate。
  • 确保你的MyDataContractSurrogate正确实现了ISerializationSurrogateProvider的所有方法:GetDeserializedObject、GetObjectToSerialize、GetKnownCustomDataTypes和GetSurrogateType。

内容的提问来源于stack exchange,提问作者HPaxton

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:51:33