Entwickler-Ecke

IO, XML und Registry - DataContractSerializer bricht Serialisierung ab (ohne Error)


C# - Do 16.06.16 14:34
Titel: DataContractSerializer bricht Serialisierung ab (ohne Error)
Hey @ll,

ich habe heute angefangen mit DataContracts zu arbeiten zwecks Serialisierung (nur lokal in eine XML Datei). Ich habe zu Testzwecken folgende Datenklasse:

Datenklasse

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
  [DataContract]
  [KnownType(typeof(ObjectWrapper))]
  [KnownType(typeof(Matrix))]
  class DataClass
  {
    [DataMember]
    public Brush Background { get; set; }

    [DataMember]
    public string Name { get; set; }

    [DataMember]
    public Color Color { get; set; }
  }

Da Brush und Color nicht serialisierbar sind (System.Windows.Media), habe ich auch eine Surrogateklasse für den DataContract erstellt:

Surrogate

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
class DataClassSurrogate : IDataContractSurrogate
  {
    public Type GetDataContractType(Type type)
    {
      if (!IsSerializable(type))
        return typeof(ObjectWrapper);
      
      return type;
    }

    public object GetDeserializedObject(object obj, Type targetType)
    {
      ObjectWrapper wrapper = obj as ObjectWrapper;
      
      return wrapper?.CreateObject() ?? obj;
    }

    public object GetObjectToSerialize(object obj, Type targetType)
    {
      if (!IsSerializable(obj.GetType()))
        return new ObjectWrapper(obj);

      return obj;
    }

      ...

Der ObjectWrapper ist einfach eine Klasse, die ein spezifisches Objekt via Reflection untersucht und dabei alle Eigenschaften die einen Setter haben. Diese werden dann inklusive der Werte in einem Dictionary<string, object> (string: Name der Eigenschaft, object: Wert der Eigenschaft) abgelegt:

Wrapper

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
  [DataContract]
  class ObjectWrapper
  { 
    [DataMember]
    public string FullQualifiedName { get; private set; }

    [DataMember]
    public Dictionary<stringobject> Properties { get; private set; } = new Dictionary<stringobject>();

    public ObjectWrapper()
    {
      
    }

    public ObjectWrapper(object target)
    {
      FullQualifiedName = target.GetType().AssemblyQualifiedName;

      PropertyInfo[] properties = target.GetType().GetProperties();

      foreach (PropertyInfo property in properties.Where(p => p.CanWrite))
        Properties.Add(property.Name, property.GetValue(target));
      
    }

    public object CreateObject()
    {
      Type type = Type.GetType(FullQualifiedName);
      object obj = Activator.CreateInstance(type);
      PropertyInfo[] properties = type.GetProperties();

      foreach (PropertyInfo property in properties.Where(p =>p.CanWrite))
        property.SetValue(obj, Properties[property.Name]);

      return obj;
    }
  }


Das Serialisieren des DataClass-Objekts klappt scheinbar ohne Probleme, ich erhalte keine Exception. Beim Deserialisieren erhalte ich dann aber eine Exception, dass ein unerwaretes Dateiende gefunden wurde. Die Datei ist tatsächlich unvollständig. Zunächst hätte ich vermutet, dass etwas nicht serialisiert werden konnte aber die Stelle an der die Datei endet erscheint mir doch sehr ungewöhnlich. Hier mal die ganze Datei (eigentlich ist nur das Ende wichtig:

XML Output

XML-Daten
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
<DataClass xmlns="http://schemas.datacontract.org/2004/07/Tests" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <Background xmlns:a="http://schemas.datacontract.org/2004/07/System.Windows.Media">
    <FullQualifiedName>System.Windows.Media.SolidColorBrush, PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35</FullQualifiedName>
    <Properties xmlns:b="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
      <b:KeyValueOfstringanyType>
        <b:Key>Color</b:Key>
        <b:Value i:type="ObjectWrapper">
          <FullQualifiedName>System.Windows.Media.Color, PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35</FullQualifiedName>
          <Properties>
            <b:KeyValueOfstringanyType>
              <b:Key>A</b:Key>
              <b:Value i:type="c:unsignedByte" xmlns:c="http://www.w3.org/2001/XMLSchema">255</b:Value>
            </b:KeyValueOfstringanyType>
            <b:KeyValueOfstringanyType>
              <b:Key>R</b:Key>
              <b:Value i:type="c:unsignedByte" xmlns:c="http://www.w3.org/2001/XMLSchema">0</b:Value>
            </b:KeyValueOfstringanyType>
            <b:KeyValueOfstringanyType>
              <b:Key>G</b:Key>
              <b:Value i:type="c:unsignedByte" xmlns:c="http://www.w3.org/2001/XMLSchema">128</b:Value>
            </b:KeyValueOfstringanyType>
            <b:KeyValueOfstringanyType>
              <b:Key>B</b:Key>
              <b:Value i:type="c:unsignedByte" xmlns:c="http://www.w3.org/2001/XMLSchema">0</b:Value>
            </b:KeyValueOfstringanyType>
            <b:KeyValueOfstringanyType>
              <b:Key>ScA</b:Key>
              <b:Value i:type="c:float" xmlns:c="http://www.w3.org/2001/XMLSchema">1</b:Value>
            </b:KeyValueOfstringanyType>
            <b:KeyValueOfstringanyType>
              <b:Key>ScR</b:Key>
              <b:Value i:type="c:float" xmlns:c="http://www.w3.org/2001/XMLSchema">0</b:Value>
            </b:KeyValueOfstringanyType>
            <b:KeyValueOfstringanyType>
              <b:Key>ScG</b:Key>
              <b:Value i:type="c:float" xmlns:c="http://www.w3.org/2001/XMLSchema">0.2158605</b:Value>
            </b:KeyValueOfstringanyType>
            <b:KeyValueOfstringanyType>
              <b:Key>ScB</b:Key>
              <b:Value i:type="c:float" xmlns:c="http://www.w3.org/2001/XMLSchema">0</b:Value>
            </b:KeyValueOfstringanyType>
          </Properties>
        </b:Value>
      </b:KeyValueOfstringanyType>
      <b:KeyValueOfstringanyType>
        <b:Key>Opacity</b:Key>
        <b:Value i:type="c:double" xmlns:c="http://www.w3.org/2001/XMLSchema">1</b:Value>
      </b:KeyValueOfstringanyType>
      <b:KeyValueOfstringanyType>
        <b:Key>Transform</b:Key>
        <b:Value i:type="ObjectWrapper">
          <FullQualifiedName>System.Windows.Media.MatrixTransform, PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35</FullQualifiedName>
          <Properties>
            <b:KeyValueOfstringanyType>
              <b:Key>Matrix</b:Key>
              <b:Value i:type="a:Matrix">
                <a:_m11>1</a:_m11>
                <a:_m12>0</a:_m12>
                <a:_m21>0</a:_m21>
                <a:_m22>1</a:_m22>
                <a:_offsetX>0</a:_offsetX>
                <a:_offsetY>0</a:_offsetY>
                <a:_padding>0</a:_padding>
                <a:_type>TRANSFORM_IS_IDENTITY</a:_type>
              </b:Value>
            </b:KeyValueOfstringanyType>
          </Properties>
        </b:Value>
      </b:KeyValueOfstringanyType>
      <b:KeyValueOfstringanyType>
        <b:Key>RelativeTransform</b:Key>
        <b:Value i:type="ObjectWrapper">
          <FullQualifiedName>System.Windows.Media.MatrixTransform, PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35</FullQualifiedName>
          <Properties>
            <b:KeyValueOfstringanyType>
              <b:Key>Matrix</b:Key>
              <b:Value i:type="a:Matrix">
                <a:_m11>1</a:_m11>
                <a:_m12>0</a:_m12>
                <a:_m21>0</a:_m21>
                <a:_m22>1</a:_m22>
                <a:_offsetX>0</a:_offsetX>
                <a:_offsetY>0</a:_offsetY>
                <a:_padding>0</a:_padding>
                <a:_type>TRANSFORM_IS_IDENTITY</a:_type>
              </b:Value>
            </b:KeyValueOfstringanyType>
          </Properties>
        </b:Value>
      </b:KeyValueOfstringanyType>
    </Properties>
  </Background>
  <Color xmlns:a="http://schemas.datacontract.org/2004/07/System.Windows.Media">
    <FullQualifiedName>System.Windows.Media.Color, PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35</FullQualifiedName>
    <Properties xmlns:b="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
      <b:KeyValueOfstringanyType>
        <b:Key>A</b:Key>
        <b:Value i:type="c:unsignedByte" xmlns:c="http://www.w3.org/2001/XMLSchema">255</b:Value>
      </b:KeyValueOfstringanyType>
      <b:KeyValueOfstringanyType>
        <b:Key>R</b:Key>
        <b:Value i:type="c:unsignedByte" xmlns:c="http://www.w3.org/2001/XMLSchema">238</b:Value>
      </b:KeyValueOfstringanyType>
      <b:KeyValueOfstringanyType>
        <b:Key>G</b:Key>
        <b:Value i:type="c:unsignedByte" xmlns:c="http://www.w3.org/2001/XMLSchema">130</b:Value>
      </b:KeyValueOfstringanyType>
      <b:KeyValueOfstringanyType>
        <b:Key>B</b:Key>
        <b:Value i:type="c:unsignedByte" xmlns:c="http://www.w3.org/2001/XMLSchema">238</b:Value>
      </b:KeyValueOfstringanyType>
      <b:KeyValueOfstringanyType>
        <b:Key>ScA</b:Key>
        <b:Value i:type="c:float" xmlns:c="http://www.w3.org/2001/XMLSchema">1</b:Value>
      </b:KeyValueOfstringanyType>
      <b:KeyValueOfstringanyType>
        <b:Key>ScR</b:Key>
        <b:Value i:type="c:float" xmlns:c="http://www.w3.org/2001/XMLSchema">0.8549926</b:Value>
      </b:KeyValueOfstringanyType>
      <b:KeyValueOfstringanyType>
        <b:Key>ScG</b:Key>
        <b:Value i:type="c:float" xmlns:c="http://www.w3.org/2001/XMLSchema">0.223227963</b:Value>
      </b:KeyValueOfstringanyType>
      <b:KeyValueOfstringanyType>
        <b:Key>ScB</b:Key>
        <b:Value i:type="c:float" xmlns:c=""

Dass sich verschiedene Typen (wie z.B. Color) besser serialisieren lassen ist mir bekannt, aber darum geht es mir hier ja nicht.

Warum bricht der Serializer mitten im Tag ab und warum wird keine Fehlermeldung geworfen?

Hier noch der Test-Code (Bei der Markierung wird die Exception geworfen):

Program.cs

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
      DataClass tester = new DataClass
      {
        Background = Brushes.Green,
        Color = Colors.Violet,
        Name = "Test Class"
      };

      DataClass result;

      DataContractSerializerSettings settings = new DataContractSerializerSettings {DataContractSurrogate = new DataClassSurrogate()};
      DataContractSerializer serializer = new DataContractSerializer(typeof(DataClass), settings);
      
      using (FileStream stream = new FileStream("test.xml", FileMode.OpenOrCreate, FileAccess.ReadWrite))
      {
        XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(stream);
        serializer.WriteObject(writer, tester);
      }

      using (FileStream stream = new FileStream("test.xml", FileMode.Open, FileAccess.Read))
      {
        XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(stream, new XmlDictionaryReaderQuotas());
        result = (DataClass)serializer.ReadObject(reader);
      }
      
      WriteLine($"Serialization succeeded: {result.Equals(tester)}");

      WriteLine("Done");
      ReadKey();



// Nachtrag

Also an den Daten kann es fast nicht liegen. Ich habe mal die Reihenfolge der Eigenschaften der DataClass geändert. Vorher war die Datei 4908 Zeichen lang. Jetzt ist sie noch 4850 Zeichen lang. Hier die neue Datei:

XML Output 2

XML-Daten
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
<DataClass xmlns="http://schemas.datacontract.org/2004/07/Tests" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <Name>Test Class</Name>
  <Color xmlns:a="http://schemas.datacontract.org/2004/07/System.Windows.Media">
    <FullQualifiedName>System.Windows.Media.Color, PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35</FullQualifiedName>
    <Properties xmlns:b="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
      <b:KeyValueOfstringanyType>
        <b:Key>A</b:Key>
        <b:Value i:type="c:unsignedByte" xmlns:c="http://www.w3.org/2001/XMLSchema">255</b:Value>
      </b:KeyValueOfstringanyType>
      <b:KeyValueOfstringanyType>
        <b:Key>R</b:Key>
        <b:Value i:type="c:unsignedByte" xmlns:c="http://www.w3.org/2001/XMLSchema">238</b:Value>
      </b:KeyValueOfstringanyType>
      <b:KeyValueOfstringanyType>
        <b:Key>G</b:Key>
        <b:Value i:type="c:unsignedByte" xmlns:c="http://www.w3.org/2001/XMLSchema">130</b:Value>
      </b:KeyValueOfstringanyType>
      <b:KeyValueOfstringanyType>
        <b:Key>B</b:Key>
        <b:Value i:type="c:unsignedByte" xmlns:c="http://www.w3.org/2001/XMLSchema">238</b:Value>
      </b:KeyValueOfstringanyType>
      <b:KeyValueOfstringanyType>
        <b:Key>ScA</b:Key>
        <b:Value i:type="c:float" xmlns:c="http://www.w3.org/2001/XMLSchema">1</b:Value>
      </b:KeyValueOfstringanyType>
      <b:KeyValueOfstringanyType>
        <b:Key>ScR</b:Key>
        <b:Value i:type="c:float" xmlns:c="http://www.w3.org/2001/XMLSchema">0.8549926</b:Value>
      </b:KeyValueOfstringanyType>
      <b:KeyValueOfstringanyType>
        <b:Key>ScG</b:Key>
        <b:Value i:type="c:float" xmlns:c="http://www.w3.org/2001/XMLSchema">0.223227963</b:Value>
      </b:KeyValueOfstringanyType>
      <b:KeyValueOfstringanyType>
        <b:Key>ScB</b:Key>
        <b:Value i:type="c:float" xmlns:c="http://www.w3.org/2001/XMLSchema">0.8549926</b:Value>
      </b:KeyValueOfstringanyType>
    </Properties>
  </Color>
  <Background xmlns:a="http://schemas.datacontract.org/2004/07/System.Windows.Media">
    <FullQualifiedName>System.Windows.Media.SolidColorBrush, PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35</FullQualifiedName>
    <Properties xmlns:b="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
      <b:KeyValueOfstringanyType>
        <b:Key>Color</b:Key>
        <b:Value i:type="ObjectWrapper">
          <FullQualifiedName>System.Windows.Media.Color, PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35</FullQualifiedName>
          <Properties>
            <b:KeyValueOfstringanyType>
              <b:Key>A</b:Key>
              <b:Value i:type="c:unsignedByte" xmlns:c="http://www.w3.org/2001/XMLSchema">255</b:Value>
            </b:KeyValueOfstringanyType>
            <b:KeyValueOfstringanyType>
              <b:Key>R</b:Key>
              <b:Value i:type="c:unsignedByte" xmlns:c="http://www.w3.org/2001/XMLSchema">0</b:Value>
            </b:KeyValueOfstringanyType>
            <b:KeyValueOfstringanyType>
              <b:Key>G</b:Key>
              <b:Value i:type="c:unsignedByte" xmlns:c="http://www.w3.org/2001/XMLSchema">128</b:Value>
            </b:KeyValueOfstringanyType>
            <b:KeyValueOfstringanyType>
              <b:Key>B</b:Key>
              <b:Value i:type="c:unsignedByte" xmlns:c="http://www.w3.org/2001/XMLSchema">0</b:Value>
            </b:KeyValueOfstringanyType>
            <b:KeyValueOfstringanyType>
              <b:Key>ScA</b:Key>
              <b:Value i:type="c:float" xmlns:c="http://www.w3.org/2001/XMLSchema">1</b:Value>
            </b:KeyValueOfstringanyType>
            <b:KeyValueOfstringanyType>
              <b:Key>ScR</b:Key>
              <b:Value i:type="c:float" xmlns:c="http://www.w3.org/2001/XMLSchema">0</b:Value>
            </b:KeyValueOfstringanyType>
            <b:KeyValueOfstringanyType>
              <b:Key>ScG</b:Key>
              <b:Value i:type="c:float" xmlns:c="http://www.w3.org/2001/XMLSchema">0.2158605</b:Value>
            </b:KeyValueOfstringanyType>
            <b:KeyValueOfstringanyType>
              <b:Key>ScB</b:Key>
              <b:Value i:type="c:float" xmlns:c="http://www.w3.org/2001/XMLSchema">0</b:Value>
            </b:KeyValueOfstringanyType>
          </Properties>
        </b:Value>
      </b:KeyValueOfstringanyType>
      <b:KeyValueOfstringanyType>
        <b:Key>Opacity</b:Key>
        <b:Value i:type="c:double" xmlns:c="http://www.w3.org/2001/XMLSchema">1</b:Value>
      </b:KeyValueOfstringanyType>
      <b:KeyValueOfstringanyType>
        <b:Key>Transform</b:Key>
        <b:Value i:type="ObjectWrapper">
          <FullQualifiedName>System.Windows.Media.MatrixTransform, PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35</FullQualifiedName>
          <Properties>
            <b:KeyValueOfstringanyType>
              <b:Key>Matrix</b:Key>
              <b:Value i:type="a:Matrix">
                <a:_m11>1</a:_m11>
                <a:_m12>0</a:_m12>
                <a:_m21>0</a:_m21>
                <a:_m22>1</a:_m22>
                <a:_offsetX>0</a:_offsetX>
                <a:_offsetY>0</a:_offsetY>
                <a:_padding>0</a:_padding>
                <a:_type>TRANSFORM_IS_IDENTITY</a:_type>
              </b:Value>
            </b:KeyValueOfstringanyType>
          </Properties>
        </b:Value>
      </b:KeyValueOfstringanyType>
      <b:KeyValueOfstringanyType>
        <b:Key>RelativeTransform</b:Key>
        <b:Value i:type="ObjectWrapper">
          <FullQualifiedName>System.Windows.Media.MatrixTransform, PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35</FullQualifiedName>
          <Properties>
            <b:KeyValueOfstringanyType>
              <b:Key>Matrix</b:Key>
              <b:Value i:type="a:Matrix">
                <a:_m11>1</a:_m11>
                <a:_m12>0</a:_m12>
                <a:_m21>0</a:_m21>
                <a:_m22>1</a:_m22>
                <a:_offsetX>0</a:_offsetX>
                <a:_offsetY>0</a:_offsetY>
                <a:


Th69 - Do 16.06.16 15:14

Hallo,

erste Vermutung von mir (ohne deinen Code genauer gesehen zu haben): fehlt evtl. ein Flush bzw. wird der Stream nicht richtig geschlossen?

Edit: doch mal deinen Code angeschaut - packe mal zwischen die beiden Streams eine Wartezeit von einigen Sekunden (nur zur Fehleranalyse).


C# - Do 16.06.16 15:21

Hey,

Flushen hat nicht geholfen das hatte ich schon probiert (die stream.Length-Eigenschaft stimmt mit der Dateilänge überein). Eine Wartezeit von 3s zwischen den Aufrufen hat leider auch nichts gebracht.


Th69 - Do 16.06.16 15:52

Aber daß die beiden XML-Dateien jeweils mittendrin aufhören, deutet trotzdem darauf hin...


Ralf Jansen - Do 16.06.16 15:53

a.) Vielleicht mal im Debugger auf stille Exceptions lauschen ob da nicht was unterwegs ist und man aus denen irgendwas ableiten kann.
b.) Ich würd nochmal über den ObjectWrapper nachdenken. Wenn ich nur Klassen serialisiere die ich selbst im Griff habe mag der teilgenerische Ansatz funktionieren, aber bei belibiegen Klassen anzunehmen das man öffentliche Properties lesen/schreiben kann und da kommt dann am Ende eine äquivalente Klasse raus wird regelmäßig schief gehen. Viele haben inneren Zustand oder wichtige Teile sind nur über den Konstruktor erreichbar oder Properties sind nicht in belibieger Reihenfolge schreibbar. Bei Color wird dir z.b-ein eventueller ColorContext flöten gehen.


C# - Do 16.06.16 17:04

Zitat:
Vielleicht mal im Debugger auf stille Exceptions lauschen ob da nicht was unterwegs ist und man aus denen irgendwas ableiten kann.

Nope, kommt nix.

Zitat:
Ich würd nochmal über den ObjectWrapper nachdenken.

Ja darum ging es mir ja jetzt nicht wie viel Sinn der macht.

Ich habe jetzt mal spezialisierte Wrapper erstellt für Brush und Color:

BrushWrapper

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
  [DataContract]
  class BrushWrapper
  {
    [DataMember(Order = 2)]
    public string FullQualifiedName { get; private set; }

    [DataMember(Order = 1)]
    public Color Color { get; private set; }
    
    [DataMember(Order = 0)]
    public double Opacity { get; private set; }

    private BrushWrapper()
    {
    }

    public BrushWrapper(Brush target)
    {
      FullQualifiedName = target.GetType().AssemblyQualifiedName;
      Opacity = target.Opacity;

      dynamic brush = target;

      if (target is SolidColorBrush)
        Color = brush.Color;
    }

    public Brush GetBrush()
    {
      Brush brush = (Brush)Activator.CreateInstance(Type.GetType(FullQualifiedName));

      PropertyInfo[] wrapperProperties = GetType().GetProperties();
      PropertyInfo[] brushProperties = brush.GetType().GetProperties();

      Dictionary<PropertyInfo, PropertyInfo> relations = brushProperties.Where(bp => wrapperProperties.Any(wp => wp.Name == bp.Name))
                                        .ToDictionary(bp => bp, bp => wrapperProperties.First(wp => wp.Name == bp.Name));

      foreach (KeyValuePair<PropertyInfo, PropertyInfo> relation in relations)
        relation.Key.SetValue(brush, relation.Value.GetValue(this));

      return brush;
    }
  }


ColorWrapper

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
  [DataContract]
  class ColorWrapper
  {
    [DataMember]
    public string Color { get; private set; }

    private ColorWrapper()
    {
    }

    public ColorWrapper(Color color)
    {
      Color = color.ToString();
    }

    public Color GetColor()
    {
      return (Color)ColorConverter.ConvertFromString(Color);
    }
  }


Dieses mal sieht der Ouput so aus:

XML Output 3

XML-Daten
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
<DataClass xmlns="http://schemas.datacontract.org/2004/07/Tests" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <Name>Test Class</Name>
  <Color xmlns:a="http://schemas.datacontract.org/2004/07/System.Windows.Media">
    <Color>#FFEE82EE</Color>
  </Color>
  <Background i:type="BrushWrapper" xmlns:a="http://schemas.datacontract.org/2004/07/System.Windows.Media">
    <Opacity>1</Opacity>
    <Color>
      <Color>#FF008000</Color>
    </Color>
    <FullQualifiedName>


Ich habe es mit verschiedenen Reihenfolgen der Eigenschaften versucht (DataMember.Order), sowohl in DataClass, als auch in BrushWrapper. Die Datei endet jedes mal bei dem <FullQualifiedName> Tag des BrushWrappers, egal wo es sich befindet. Ich weiß jedoch nicht warum, die Werte im Debugger sind in Ordnung.


Th69 - Do 16.06.16 18:29

Setze auch mal den XmlDictionaryWriter/-Reader in eine using-Anweisung, denn auch dieser hat eine Dispose() [https://msdn.microsoft.com/de-de/library/system.xml.xmldictionarywriter.dispose(v=vs.110).aspx]-Methode...


C# - Fr 17.06.16 10:11

Vielen vielen Dank.

Ich habe übersehen dass auch der DictionaryWriter IDisposable implementiert :autsch:
Jetzt klappt alles.

Danke für eure Mühen