接受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));
以下是我为使消息序列化和反序列化所做的工作。请注意,反序列化版本已丢失其复杂类型,并且所有集合都已转换为数组。这对我来说已经足够了。
[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);
}
}