接受WCF对象参数的不同类型

本文关键字:同类型 参数 WCF 对象 接受 | 更新日期: 2023-09-27 18:21:26

我希望能够接受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调用引发(反)序列化异常。有没有允许不同类型的技巧?

编辑

一些上下文:

由于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));

接受WCF对象参数的不同类型

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

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