接受WCF对象参数

时间:2015-11-09 21:46:30

标签: c# wcf serialization

我希望能够接受WCF调用的所有参数。实际签名是这样的:

[DataContract]
public class Message
{
    private Message() {}

    public static Message Create(MessageTypeEnum type, params object[] parameters)
    {
        return new Message {MessageType = type, Parameters = parameters};
    }

    [DataMember]
    public MessageTypeEnum MessageType { get; private set; }

    [DataMember]
    public object[] Parameters { get; private set; }
}


public void SendMessage(Message message)
{
   var receivers = GetReceiversByMessageType(Message.MessageType);
   foreach(var receiver in receivers)
   {
      var template = GetMessage(type, receiver.Locale)
      var text = string.Format(template, receiver.Locale, Message.Parameters);
      SendMessage(receiver.Address, text);
   }
}

消息调用适用于简单类型,如整数,日期和字符串。 但是,我希望能够发送元组和数组数组。 (我实际上使用了支持此功能的不同格式化方法)

我的WCF调用抛出(de)序列化异常。是否有允许不同类型的技巧?

编辑

某些背景信息:

由于WCF用于在我们的Web服务器和业务逻辑服务器之间进行通信,因此这是一项要求。应该总是有充分的理由偏离标准,我认为简单的警报器不符合要求。

在我们的实际解决方案中,使用单独的Message对象。我可以更改消息序列化的客户端和服务器端。我无法更改消息创建方法,因为它在太多地方使用。

这有效:

var msg = Message.Create(MessageTypeEnum.InvalidName, "Petr");
Clients.MessageClient(c => c.SendMessage(msg));

这不是:

var msg = Message.Create(MessageTypeEnum.InvalidNames, new[] {"Petr", "Jann"};
Clients.MessageClient(c => c.SendMessage(msg));

1 个答案:

答案 0 :(得分:0)

这是我想出的消息序列化和反序列化。请注意,反序列化版本已丢失其复杂类型,并且所有集合都已转换为数组。这对我的目的来说已经足够了。

[DataContract]
public class Message
{
    public static Message Create(MessageTypeEnum type, params object[] parameters)
    {
        return new Message {MessageType = type, Parameters = parameters};
    }

    [DataMember]
    public MessageTypeEnum MessageType { get; set; }

    public IList<object> Parameters { get; set; }

    [DataMember]
    public IList<string> SerializedParameters
    {
        get { return Parameters.Select(JsonConvert.SerializeObject).ToArray(); }
        set { Parameters = value.Select(DeserializeObject).ToArray(); }
    }

    private object DeserializeObject(string json)
    {
        return ReplaceArrays(JsonConvert.DeserializeObject(json));
    }

    private object ReplaceArrays(object obj)
    {
        var dictionary = obj as IDictionary<string, JToken>;
        if (dictionary != null) return dictionary.ToDictionary(kvp => kvp.Key, kvp => ReplaceArrays(kvp.Value));
        var collection = obj as JArray;
        if (collection != null) return collection.Cast<object>().Select(ReplaceArrays).ToArray();
        var jValue = obj as JValue;
        if (jValue != null) return jValue.Value;
        return obj;
    }
}

(...)

public void SendMessage(Message message)
{
   var receivers = GetReceiversByMessageType(Message.MessageType);
   foreach(var receiver in receivers)
   {
      var template = GetMessage(type, receiver.Locale)
      var text = string.Format(template, receiver.Locale, Message.Parameters);
      SendMessage(receiver.Address, text);
   }
}