我希望能够接受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));
答案 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);
}
}