Got any simular ideas that can be used for that type of thing. More or less
a key/value string pair that can be serialized?
> No, this has not changed in 3.5.
>
>> Is it possible to serialize to xml a dictionary<string, string> object in
>> ..net 3.5?
Not sure if this is a great idea, but it works:
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using System.IO;
using System.ComponentModel;
using System.Collections.Specialized;
class Program
{
static void Main()
{
Foo foo = new Foo
{
Values =
{
{ "abc", "def" },
{ "ghi", "jkl" }
}
};
XmlSerializer ser = new XmlSerializer(typeof(Foo));
StringWriter writer = new StringWriter();
ser.Serialize(writer, foo);
string xml = writer.ToString();
StringReader reader = new StringReader(xml);
Foo newFoo = (Foo) ser.Deserialize(reader);
foreach (KeyValuePair<string, string> pair in newFoo.Values)
{
Console.WriteLine(pair.Key + ": " + pair.Value);
}
}
}
[Serializable]
public class Foo
{
private readonly Dictionary<string, string> values
= new Dictionary<string,string>();
[XmlIgnore]
public Dictionary<string, string> Values { get { return
values; } }
[EditorBrowsable(EditorBrowsableState.Never)]
[XmlArray(ElementName="Values")]
[XmlArrayItem(ElementName="Add", Type=typeof(StringPair))]
public StringPairList ValuesProxy
{
get { return new StringPairList(values); }
}
}
[Serializable]
public class StringPairList : IList<StringPair>
{
private readonly IDictionary<string,string> parent;
public StringPairList(IDictionary<string, string> parent)
{
if (parent == null) throw new ArgumentNullException("parent");
this.parent = parent;
}
#region IList<StringPair> Members
public int IndexOf(StringPair item)
{
throw new NotImplementedException();
}
public void Insert(int index, StringPair item)
{
throw new NotImplementedException();
}
public void RemoveAt(int index)
{
throw new NotImplementedException();
}
public StringPair this[int index]
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
#endregion
#region ICollection<StringPair> Members
public void Add(StringPair item)
{
parent.Add(item.Key, item.Value);
}
public void Clear()
{
parent.Clear();
}
public bool Contains(StringPair item)
{
throw new NotImplementedException();
}
public void CopyTo(StringPair[] array, int arrayIndex)
{
throw new NotImplementedException();
}
public int Count
{
get { return parent.Count; }
}
public bool IsReadOnly
{
get { return false; }
}
public bool Remove(StringPair item)
{
throw new NotImplementedException();
}
#endregion
#region IEnumerable<StringPair> Members
public IEnumerator<StringPair> GetEnumerator()
{
foreach (var pair in parent)
{
yield return new StringPair
{
Key = pair.Key,
Value = pair.Value
};
}
}
#endregion
#region IEnumerable Members
System.Collections.IEnumerator
System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion
}
[Serializable]
public class StringPair
{
[XmlAttribute]
public string Key { get; set; }
[XmlAttribute]
public string Value { get; set; }
}
Marc Gravell - 07 Apr 2008 07:46 GMT
Actually, it looks like it only needs IEnumerable<StringPair>
and Add(StringPair) - I incorrectly assumed it would use the
Add method from IList<StringPair> (in fact it finds the Add
separately); removing all the dross
makes the solution far less grungy - satisfactory, even.
Example (K&R for brevity):
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Xml.Serialization;
static class Program {
static void Main() {
Foo foo = new Foo {
Values = {
{ "abc", "def" },
{ "ghi", "jkl" }
}
};
XmlSerializer ser = new XmlSerializer(typeof(Foo));
StringWriter writer = new StringWriter();
ser.Serialize(writer, foo);
string xml = writer.ToString();
StringReader reader = new StringReader(xml);
Foo newFoo = (Foo) ser.Deserialize(reader);
foreach (KeyValuePair<string, string> pair in newFoo.Values) {
Console.WriteLine(pair.Key + ": " + pair.Value);
}
}
}
[Serializable]
public class Foo {
private readonly Dictionary<string, string> values
= new Dictionary<string,string>();
[XmlIgnore]
public Dictionary<string, string> Values { get { return
values; } }
[EditorBrowsable(EditorBrowsableState.Never)]
[XmlArray(ElementName="Values")]
[XmlArrayItem(ElementName="add", Type=typeof(StringPair))]
public StringPairList ValuesProxy {
get { return new StringPairList(values); }
}
}
[Serializable]
public sealed class StringPairList : IEnumerable<StringPair> {
private readonly IDictionary<string,string> parent;
public StringPairList(IDictionary<string, string> parent) {
if (parent == null) throw new ArgumentNullException("parent");
this.parent = parent;
}
public void Add(StringPair item) {
parent.Add(item.Key, item.Value);
}
public IEnumerator<StringPair> GetEnumerator() {
foreach (var pair in parent) {
yield return new StringPair {
Key = pair.Key, Value = pair.Value
};
}
}
IEnumerator IEnumerable.GetEnumerator() {
return GetEnumerator();
}
}
[Serializable]
public sealed class StringPair {
[XmlAttribute("key")]
public string Key { get; set; }
[XmlAttribute("value")]
public string Value { get; set; }
}
There is the SerializableDictionary class that I pointed someone to last
week. I don't recall if you were in that discussion. If not, the link is
http://weblogs.asp.net/pwelter34/archive/2006/05/03/444961.aspx.
> Got any simular ideas that can be used for that type of thing. More or less
> a key/value string pair that can be serialized?
[quoted text clipped - 3 lines]
> >> Is it possible to serialize to xml a dictionary<string, string> object in
> >> ..net 3.5?
Marc Gravell - 07 Apr 2008 12:57 GMT
> There is the SerializableDictionary class that I pointed someone to last
> week. I don't recall if you were in that discussion. If not, the link is
> http://weblogs.asp.net/pwelter34/archive/2006/05/03/444961.aspx.
I must have skipped that one ;-p
It looks like another viable solution; one caveat with
SerializableDictionary is that the schema isn't very well defined (in
terms of a WSDL or similar - I believe it uses "any") - but it will
work. And less effort than adding attributes and a facade property...
Marc