.NET에 직렬화 가능한 일반 키 / 값 쌍 클래스가 있습니까?
웹 서비스에 포함 할 수있는 키 / 값 쌍 개체를 찾고 있습니다.
.NET의 System.Collections.Generic.KeyValuePair<>
클래스를 사용해 보았지만 웹 서비스에서 제대로 직렬화되지 않습니다. 웹 서비스에서 Key 및 Value 속성은 직렬화되지 않으므로 누군가이 문제를 해결할 방법을 알지 못하는 경우이 클래스를 쓸모 없게 만듭니다.
이 상황에 사용할 수있는 다른 일반 클래스가 있습니까?
.NET의 System.Web.UI.Pair
클래스를 사용하지만 유형에 대해 Object를 사용합니다. 타입 안전성을 위해서만 Generic 클래스를 사용하는 것이 좋습니다.
구조체 / 클래스를 정의하기 만하면됩니다.
[Serializable]
public struct KeyValuePair<K,V>
{
public K Key {get;set;}
public V Value {get;set;}
}
나는이 없다고 생각 Dictionary<>
자체가 XML의 직렬화 할 수없는 나는 내가 포장 결국 웹 서비스를 통해 사전 개체를 보낼 필요했을 때, 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
}
이 MSDN 블로그 게시물 에서 KeyValuePairs를 직렬화 할 수없는 이유를 확인할 수 있습니다.
Struct 대답은 가장 간단한 해결책이지만 유일한 해결책은 아닙니다. "더 나은"솔루션은 Serializable 인 Custom KeyValurPair 클래스를 작성하는 것입니다.
[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.0 프레임 워크에는 직렬화 가능하고 동등하게 사용할 수있는 Tuple 클래스 클래스가 추가되었습니다. 당신은 사용할 수 있습니다 Tuple.Create(a, b)
또는 new Tuple<T1, T2>(a, b)
.
A KeyedCollection is a type of dictionary that can be directly serialized to xml without any nonsense. The only issue is that you have to access values by: coll["key"].Value;
XmlSerializer doesn't work with Dictionaries. Oh, and it has problems with KeyValuePairs too
http://www.codeproject.com/Tips/314447/XmlSerializer-doesnt-work-with-Dictionaries-Oh-and
Use the DataContractSerializer since it can handle the Key Value Pair.
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();
}
}
DataTable
is my favorite collection for (solely) wrapping data to be serialized to JSON, since it's easy to expand without the need for an extra struct
& acts like a serializable replacement for Tuple<>[]
Maybe not the cleanest way, but I prefer to include & use it directly in the classes (which shall be serialized), instead of declaring a new struct
class AnyClassToBeSerialized
{
public DataTable KeyValuePairs { get; }
public AnyClassToBeSerialized
{
KeyValuePairs = new DataTable();
KeyValuePairs.Columns.Add("Key", typeof(string));
KeyValuePairs.Columns.Add("Value", typeof(string));
}
public void AddEntry(string key, string value)
{
DataRow row = KeyValuePairs.NewRow();
row["Key"] = key; // "Key" & "Value" used only for example
row["Value"] = value;
KeyValuePairs.Rows.Add(row);
}
}
You can use Tuple<string,object>
see this for more details on Tuple
usage : Working with Tuple in C# 4.0
'development' 카테고리의 다른 글
Bash 스크립트에서 오류 발생 (0) | 2020.10.12 |
---|---|
명령 줄 도구 bash (git)가 작동하지 않음-macOS Sierra 최종 릴리스 후보 (0) | 2020.10.12 |
emacs에서 줄 / 영역을 위아래로 이동 (0) | 2020.10.12 |
ListView에서 바닥 글보기를 숨기시겠습니까? (0) | 2020.10.12 |
부하 대 스트레스 테스트 (0) | 2020.10.12 |