我正在寻找一个可以包含在Web服务中的键/值对对象。
我尝试使用.NET的System.Collections.Generic.KeyValuePair<>
类,但它没有在Web服务中正确序列化。在Web服务中,Key和Value属性未被序列化,使得此类无用,除非有人知道解决此问题的方法。
是否有其他可用于此情况的通用类?
我使用.NET的System.Web.UI.Pair
类,但它使用Object作为其类型。如果仅用于类型安全,那么使用Generic类会很好。
答案 0 :(得分:91)
只需定义一个struct / class。
[Serializable]
public struct KeyValuePair<K,V>
{
public K Key {get;set;}
public V Value {get;set;}
}
答案 1 :(得分:22)
我不认为有Dictionary<>
本身不是XML可序列化的,当我需要通过Web服务发送字典对象时,我最终自己包装Dictionary<>
对象并添加支持IXMLSerializable
。
/// <summary>
/// Represents an XML serializable collection of keys and values.
/// </summary>
/// <typeparam name="TKey">The type of the keys in the dictionary.</typeparam>
/// <typeparam name="TValue">The type of the values in the dictionary.</typeparam>
[XmlRoot("dictionary")]
public class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, IXmlSerializable
{
#region Constants
/// <summary>
/// The default XML tag name for an item.
/// </summary>
private const string DEFAULT_ITEM_TAG = "Item";
/// <summary>
/// The default XML tag name for a key.
/// </summary>
private const string DEFAULT_KEY_TAG = "Key";
/// <summary>
/// The default XML tag name for a value.
/// </summary>
private const string DEFAULT_VALUE_TAG = "Value";
#endregion
#region Protected Properties
/// <summary>
/// Gets the XML tag name for an item.
/// </summary>
protected virtual string ItemTagName
{
get
{
return DEFAULT_ITEM_TAG;
}
}
/// <summary>
/// Gets the XML tag name for a key.
/// </summary>
protected virtual string KeyTagName
{
get
{
return DEFAULT_KEY_TAG;
}
}
/// <summary>
/// Gets the XML tag name for a value.
/// </summary>
protected virtual string ValueTagName
{
get
{
return DEFAULT_VALUE_TAG;
}
}
#endregion
#region Public Methods
/// <summary>
/// Gets the XML schema for the XML serialization.
/// </summary>
/// <returns>An XML schema for the serialized object.</returns>
public XmlSchema GetSchema()
{
return null;
}
/// <summary>
/// Deserializes the object from XML.
/// </summary>
/// <param name="reader">The XML representation of the object.</param>
public void ReadXml(XmlReader reader)
{
XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));
bool wasEmpty = reader.IsEmptyElement;
reader.Read();
if (wasEmpty)
{
return;
}
while (reader.NodeType != XmlNodeType.EndElement)
{
reader.ReadStartElement(ItemTagName);
reader.ReadStartElement(KeyTagName);
TKey key = (TKey)keySerializer.Deserialize(reader);
reader.ReadEndElement();
reader.ReadStartElement(ValueTagName);
TValue value = (TValue)valueSerializer.Deserialize(reader);
reader.ReadEndElement();
this.Add(key, value);
reader.ReadEndElement();
reader.MoveToContent();
}
reader.ReadEndElement();
}
/// <summary>
/// Serializes this instance to XML.
/// </summary>
/// <param name="writer">The writer to serialize to.</param>
public void WriteXml(XmlWriter writer)
{
XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));
foreach (TKey key in this.Keys)
{
writer.WriteStartElement(ItemTagName);
writer.WriteStartElement(KeyTagName);
keySerializer.Serialize(writer, key);
writer.WriteEndElement();
writer.WriteStartElement(ValueTagName);
TValue value = this[key];
valueSerializer.Serialize(writer, value);
writer.WriteEndElement();
writer.WriteEndElement();
}
}
#endregion
}
答案 2 :(得分:17)
您将找到无法在此MSDN Blog Post
序列化KeyValuePairs的原因结构答案是最简单的解决方案,但不是唯一的解决方案。一个“更好”的解决方案是编写一个Custom SerialValurPair类,它是Serializable。
答案 3 :(得分:6)
[Serializable]
public class SerializableKeyValuePair<TKey, TValue>
{
public SerializableKeyValuePair()
{
}
public SerializableKeyValuePair(TKey key, TValue value)
{
Key = key;
Value = value;
}
public TKey Key { get; set; }
public TValue Value { get; set; }
}
答案 4 :(得分:1)
在4.0 Framework中,还添加了可序列化且可等同的Tuple类。您可以使用Tuple.Create(a, b)
或new Tuple<T1, T2>(a, b)
。
答案 5 :(得分:0)
KeyedCollection是一种字典,可以直接序列化为xml而不会产生任何废话。唯一的问题是您必须通过以下方式访问值:coll [“key”]。值;
答案 6 :(得分:0)
XmlSerializer不适用于字典。哦,它也有KeyValuePairs的问题
http://www.codeproject.com/Tips/314447/XmlSerializer-doesnt-work-with-Dictionaries-Oh-and
答案 7 :(得分:0)
使用DataContractSerializer,因为它可以处理键值对。
public static string GetXMLStringFromDataContract(object contractEntity)
{
using (System.IO.MemoryStream writer = new System.IO.MemoryStream())
{
var dataContractSerializer = new DataContractSerializer(contractEntity.GetType());
dataContractSerializer.WriteObject(writer, contractEntity);
writer.Position = 0;
var streamReader = new System.IO.StreamReader(writer);
return streamReader.ReadToEnd();
}
}
答案 8 :(得分:0)
DataTable
是我最喜欢的(仅)包装要序列化为JSON的包装数据的集合,因为它易于扩展,而无需额外的struct
且就像{{1 }}
也许不是最干净的方法,但我更喜欢直接在类(应进行序列化)中包含并使用它,而不是声明新的Tuple<>[]
struct
答案 9 :(得分:-3)
您可以使用Tuple<string,object>
有关Tuple
用法的详细信息,请参阅此处:Working with Tuple in C# 4.0