it-swarm-id.com

Apakah ada kelas pasangan Kunci/Nilai generik berseri dalam.

Saya mencari objek pasangan kunci/nilai yang dapat saya sertakan dalam layanan web.

Saya mencoba menggunakan .NET's System.Collections.Generic.KeyValuePair<> class, tetapi tidak membuat serialisasi dengan benar di layanan web. Dalam layanan web, properti Key dan Value tidak bersambung, membuat kelas ini tidak berguna, kecuali seseorang tahu cara untuk memperbaikinya.

Apakah ada kelas generik lain yang dapat digunakan untuk situasi ini?

Saya akan menggunakan .NET's System.Web.UI.Pair class, tetapi ia menggunakan Object untuk tipenya. Akan menyenangkan menggunakan kelas Generik, jika hanya untuk keamanan tipe.

74
Dan Herbert

Cukup tentukan struct/kelas.

[Serializable]
public struct KeyValuePair<K,V>
{
  public K Key {get;set;}
  public V Value {get;set;}
}
90
leppie

Saya tidak berpikir ada Dictionary<> itu sendiri bukan XML serializable, ketika saya harus mengirim objek kamus melalui layanan web saya akhirnya membungkus objek Dictionary<> sendiri dan menambahkan dukungan untuk 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
}
22
Compile This

Anda akan menemukan alasan mengapa KeyValuePairs tidak dapat diserialisasi di MSDN Blog Post

Jawaban Struct adalah solusi paling sederhana, namun bukan satu-satunya solusi. Solusi "lebih baik" adalah menulis kelas Custom KeyValurPair yang Serializable.

17
user56931
 [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; }

    }
5
GregoryBrad

Dalam Kerangka 4.0, ada juga penambahan keluarga Tuple dari kelas yang serializable dan setara. Anda dapat menggunakan Tuple.Create(a, b) atau new Tuple<T1, T2>(a, b).

1
Peter Oehlert

Gunakan DataContractSerializer karena dapat menangani Pasangan Nilai Kunci.

    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();
        }
    }
0
Hasse

KeyedCollection adalah jenis kamus yang dapat langsung diserialisasi ke xml tanpa omong kosong. Satu-satunya masalah adalah Anda harus mengakses nilai dengan: coll ["key"]. Value;

0
Will

DataTable adalah koleksi favorit saya untuk (semata-mata) pembungkus data yang akan diserialkan ke JSON, karena mudah untuk diperluas tanpa perlu struct ekstra & bertindak seperti pengganti yang dapat diserialisasi untuk Tuple<>[]

Mungkin bukan cara terbersih, tapi saya lebih suka memasukkan & menggunakannya langsung di kelas (yang akan diserialisasi), daripada mendeklarasikan struct baru

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);
    }
}
0
Teodor Tite

XmlSerializer tidak berfungsi dengan Kamus. Oh, dan juga ada masalah dengan KeyValuePairs

http://www.codeproject.com/Tips/314447/XmlSerializer-doesnt-work-with-Dictionaries-Oh-and

0
Akodo_Shado