Пользовательская сериализация WCF на основе параметров - PullRequest
1 голос
/ 15 февраля 2011

Могу ли я реализовать некоторую пользовательскую сериализацию (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; }
}

Метод WCF:

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>

SOAP-ответ (упрощенный):

<GetPartVideo>
  <MethodParameters>
    <Video>
      <Description>Description of the Test Video</Description>
      <Name>Test Video</Name>
    </Video>
  </MethodParameters>
</GetPartVideo>

1 Ответ

2 голосов
/ 18 февраля 2011

Я нашел ответ сам.

Можно использовать атрибут формата сериализатора, чтобы изменить сериализацию

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));
    }
}

также класс MyCustomDataContractSerializer должен переопределить XmlObjectSerializer

и Сервис может быть украшен атрибутами пользовательского формата

[ServiceContract(Namespace = "http://tesmpuri.com/")]
[ServiceKnownType(typeof(Video))]
public interface IPartialResponseTestService
{
    [OperationContract]
    Video GetFullVideo();

    [OperationContract]
    [CustomDataContractFormat]
    Video GetPartVideo(params string[] fields);

    [OperationContract]
    [XmlSerializerFormat]
    Video GetVideo();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...