C# 基于参数的WCF自定义序列化

C# 基于参数的WCF自定义序列化,c#,soap,wcf,C#,Soap,Wcf,我可以实现一些自定义序列化(SOAP)来只序列化可以动态更改的字段吗 类别: [DataContract] public class Video { ... [DataMember] public int Width { get; set; } [DataMember] public int Height { get; set; } [DataMember] public short Bitrate { get; set; }

我可以实现一些自定义序列化(SOAP)来只序列化可以动态更改的字段吗

类别:

[DataContract]
public class Video
{
    ...

    [DataMember]
    public int Width { get; set; }

    [DataMember]
    public int Height { get; set; }

    [DataMember]
    public short Bitrate { get; set; }

    [DataMember]
    public short Framerate { get; set; }

    [DataMember]
    public long Duration { get; set; }

    [DataMember(EmitDefaultValue = false)]
    public VideoType Type { get; set; }
}
public Video GetPartVideo(params string[] fields)
{
    var video = new Video
    {
        Name = "Test Video",
        Description = "Description of the Test Video",
        CreatedAt = DateTime.Now,
        ModifiedAt = DateTime.Now,
        Url = "",
        FileName = "",
        FileSize = 100,
        Width = 640,
        Height = 480,
        Bitrate = 120,
        Framerate = 32,
        Duration = 100200300,
        Type = VideoType.StandardDefinition
    };

    return video;
} 
<GetPartVideo>
  <MethodParameters>
    <fields attr0="StringArray" isNull="false">
      <StringArray0>Name</StringArray0>
      <StringArray1>Description</StringArray1>
    </fields>
  </MethodParameters>
</GetPartVideo>
<GetPartVideo>
  <MethodParameters>
    <Video>
      <Description>Description of the Test Video</Description>
      <Name>Test Video</Name>
    </Video>
  </MethodParameters>
</GetPartVideo>
WCF方法:

[DataContract]
public class Video
{
    ...

    [DataMember]
    public int Width { get; set; }

    [DataMember]
    public int Height { get; set; }

    [DataMember]
    public short Bitrate { get; set; }

    [DataMember]
    public short Framerate { get; set; }

    [DataMember]
    public long Duration { get; set; }

    [DataMember(EmitDefaultValue = false)]
    public VideoType Type { get; set; }
}
public Video GetPartVideo(params string[] fields)
{
    var video = new Video
    {
        Name = "Test Video",
        Description = "Description of the Test Video",
        CreatedAt = DateTime.Now,
        ModifiedAt = DateTime.Now,
        Url = "",
        FileName = "",
        FileSize = 100,
        Width = 640,
        Height = 480,
        Bitrate = 120,
        Framerate = 32,
        Duration = 100200300,
        Type = VideoType.StandardDefinition
    };

    return video;
} 
<GetPartVideo>
  <MethodParameters>
    <fields attr0="StringArray" isNull="false">
      <StringArray0>Name</StringArray0>
      <StringArray1>Description</StringArray1>
    </fields>
  </MethodParameters>
</GetPartVideo>
<GetPartVideo>
  <MethodParameters>
    <Video>
      <Description>Description of the Test Video</Description>
      <Name>Test Video</Name>
    </Video>
  </MethodParameters>
</GetPartVideo>
方法调用:

[DataContract]
public class Video
{
    ...

    [DataMember]
    public int Width { get; set; }

    [DataMember]
    public int Height { get; set; }

    [DataMember]
    public short Bitrate { get; set; }

    [DataMember]
    public short Framerate { get; set; }

    [DataMember]
    public long Duration { get; set; }

    [DataMember(EmitDefaultValue = false)]
    public VideoType Type { get; set; }
}
public Video GetPartVideo(params string[] fields)
{
    var video = new Video
    {
        Name = "Test Video",
        Description = "Description of the Test Video",
        CreatedAt = DateTime.Now,
        ModifiedAt = DateTime.Now,
        Url = "",
        FileName = "",
        FileSize = 100,
        Width = 640,
        Height = 480,
        Bitrate = 120,
        Framerate = 32,
        Duration = 100200300,
        Type = VideoType.StandardDefinition
    };

    return video;
} 
<GetPartVideo>
  <MethodParameters>
    <fields attr0="StringArray" isNull="false">
      <StringArray0>Name</StringArray0>
      <StringArray1>Description</StringArray1>
    </fields>
  </MethodParameters>
</GetPartVideo>
<GetPartVideo>
  <MethodParameters>
    <Video>
      <Description>Description of the Test Video</Description>
      <Name>Test Video</Name>
    </Video>
  </MethodParameters>
</GetPartVideo>

名称
描述
SOAP响应(简化):

[DataContract]
public class Video
{
    ...

    [DataMember]
    public int Width { get; set; }

    [DataMember]
    public int Height { get; set; }

    [DataMember]
    public short Bitrate { get; set; }

    [DataMember]
    public short Framerate { get; set; }

    [DataMember]
    public long Duration { get; set; }

    [DataMember(EmitDefaultValue = false)]
    public VideoType Type { get; set; }
}
public Video GetPartVideo(params string[] fields)
{
    var video = new Video
    {
        Name = "Test Video",
        Description = "Description of the Test Video",
        CreatedAt = DateTime.Now,
        ModifiedAt = DateTime.Now,
        Url = "",
        FileName = "",
        FileSize = 100,
        Width = 640,
        Height = 480,
        Bitrate = 120,
        Framerate = 32,
        Duration = 100200300,
        Type = VideoType.StandardDefinition
    };

    return video;
} 
<GetPartVideo>
  <MethodParameters>
    <fields attr0="StringArray" isNull="false">
      <StringArray0>Name</StringArray0>
      <StringArray1>Description</StringArray1>
    </fields>
  </MethodParameters>
</GetPartVideo>
<GetPartVideo>
  <MethodParameters>
    <Video>
      <Description>Description of the Test Video</Description>
      <Name>Test Video</Name>
    </Video>
  </MethodParameters>
</GetPartVideo>

测试视频的描述
测试视频

我自己找到了答案

可以使用Serializer Format属性来更改序列化

public class CustomDataContractSerializerOperationBehavior : DataContractSerializerOperationBehavior
{
    public CustomDataContractSerializerOperationBehavior(OperationDescription operationDescription) : base(operationDescription) { }

    public override XmlObjectSerializer CreateSerializer(Type type, string name, string ns, IList<Type> knownTypes)
    {
        var dictionary = new XmlDictionary(2);
        dictionary.Add(name);
        dictionary.Add(ns);


        return new MyCustomDataContractSerializer(
            type,
            new XmlDictionaryString(dictionary, name, 0),
            new XmlDictionaryString(dictionary, ns, 1), 
            knownTypes);
    }

    public override XmlObjectSerializer CreateSerializer(Type type, XmlDictionaryString name, XmlDictionaryString ns, IList<Type> knownTypes)
    {
        return new MyCustomDataContractSerializer(
            type,
            name,
            ns,
            knownTypes);
    }
}


public class CustomDataContractFormatAttribute : Attribute, IOperationBehavior
{
    public void AddBindingParameters(OperationDescription description, BindingParameterCollection parameters)
    {
    }

    public void ApplyClientBehavior(OperationDescription description, ClientOperation proxy)
    {
        ReplaceDataContractSerializerOperationBehavior(description);
    }

    public void ApplyDispatchBehavior(OperationDescription description, DispatchOperation dispatch)
    {
        ReplaceDataContractSerializerOperationBehavior(description);
    }

    public void Validate(OperationDescription description)
    {
    }

    private static void ReplaceDataContractSerializerOperationBehavior(OperationDescription description)
    {
        DataContractSerializerOperationBehavior dcs = description.Behaviors.Find<DataContractSerializerOperationBehavior>();

        if (dcs != null)
            description.Behaviors.Remove(dcs);

        description.Behaviors.Add(new CustomDataContractSerializerOperationBehavior(description));
    }
}