CSLA.NET 5.4.2
CSLA .NET is a software development framework that helps you build a reusable, maintainable object-oriented business layer for your app.
MobileFormatter.cs
Go to the documentation of this file.
1//-----------------------------------------------------------------------
2// <copyright file="SerializationFormatterFactory.GetFormatter().cs" company="Marimer LLC">
3// Copyright (c) Marimer LLC. All rights reserved.
4// Website: https://cslanet.com
5// </copyright>
6// <summary>Serializes and deserializes objects</summary>
7//-----------------------------------------------------------------------
8using System;
9using System.Collections.Generic;
10using System.IO;
11using System.Linq;
12using System.Runtime.Serialization;
13using Csla.Properties;
14using Csla.Reflection;
15
17{
22#if TESTING
23 [System.Diagnostics.DebuggerStepThrough]
24#endif
26 {
27 #region Serialize
28
40 public void Serialize(Stream serializationStream, object graph)
41 {
42 ICslaWriter writer = CslaReaderWriterFactory.GetCslaWriter();
43 writer.Write(serializationStream, SerializeToDTO(graph));
44 }
45
50 byte[] ISerializationFormatter.Serialize(object graph)
51 {
52 using var buffer = new MemoryStream();
53 Serialize(buffer, graph);
54 buffer.Position = 0;
55 return buffer.ToArray();
56 }
57
65 public List<SerializationInfo> SerializeAsDTO(object graph)
66 {
67 _serializationReferences.Clear();
68
69 SerializeObject(graph);
70
71 ConvertEnumsToIntegers();
72 List<SerializationInfo> serialized = _serializationReferences.Values.ToList();
73
74 return serialized;
75 }
76
92 private void ConvertEnumsToIntegers()
93 {
94 foreach (SerializationInfo serializationInfo in _serializationReferences.Values)
95 {
96 foreach (SerializationInfo.FieldData fieldData in serializationInfo.Values.Values)
97 {
98 if (fieldData.Value != null)
99 {
100 Type fieldType = fieldData.Value.GetType();
101
102 if (fieldType.IsEnum)
103 {
104 fieldData.Value = Convert.ChangeType(fieldData.Value, Enum.GetUnderlyingType(fieldType));
105 fieldData.EnumTypeName = fieldType.AssemblyQualifiedName;
106 }
107 }
108 }
109 }
110 }
111
118 {
120 if (obj == null)
121 {
122 NullPlaceholder nullPlaceholder = new NullPlaceholder();
123
124 info = new SerializationInfo(_serializationReferences.Count + 1);
125 _serializationReferences.Add(nullPlaceholder, info);
126
127 info.TypeName = AssemblyNameTranslator.GetAssemblyQualifiedName(typeof(NullPlaceholder));
128 }
129 else
130 {
131 var thisType = obj.GetType();
132 if (obj is System.Security.Claims.ClaimsPrincipal cp)
133 {
134 obj = new Security.CslaClaimsPrincipal(cp);
135 thisType = obj.GetType();
136 }
137 if (!thisType.IsSerializable)
138 throw new InvalidOperationException(
139 string.Format(Resources.ObjectNotSerializableFormatted, thisType.FullName));
140 if (!(obj is IMobileObject mobile))
141 throw new InvalidOperationException(
143 thisType.Name));
144
145 if (!_serializationReferences.TryGetValue(mobile, out info))
146 {
147 info = new SerializationInfo(_serializationReferences.Count + 1);
148 _serializationReferences.Add(mobile, info);
149
150 info.TypeName = AssemblyNameTranslator.GetAssemblyQualifiedName(thisType);
151 if (thisType.Equals(typeof(Security.CslaClaimsPrincipal)))
152 {
153 var principal = (Security.CslaClaimsPrincipal)obj;
154 using (var buffer = new System.IO.MemoryStream())
155 {
156 using (var writer = new System.IO.BinaryWriter(buffer))
157 {
158 principal.WriteTo(writer);
159 info.AddValue("s", buffer.ToArray());
160 }
161 }
162 }
163 else
164 {
165 mobile.GetChildren(info, this);
166 mobile.GetState(info);
167 }
168 }
169 }
170 return info;
171 }
172
173 private Dictionary<IMobileObject, SerializationInfo> _serializationReferences =
174 new Dictionary<IMobileObject, SerializationInfo>(new ReferenceComparer<IMobileObject>());
175
176#endregion
177
178#region Deserialize
179
180 private Dictionary<int, IMobileObject> _deserializationReferences =
181 new Dictionary<int, IMobileObject>();
182
183 private Dictionary<string, Type> _typeCache = new Dictionary<string, Type>();
184
185 private Type GetTypeFromCache(string typeName)
186 {
187 Type result;
188 if (!_typeCache.TryGetValue(typeName, out result))
189 {
190 result = Csla.Reflection.MethodCaller.GetType(typeName);
191
192 if (result == null)
193 {
194 throw new SerializationException(string.Format(
196 typeName));
197 }
198 _typeCache.Add(typeName, result);
199 }
200
201 return result;
202 }
203
212 public object Deserialize(Stream serializationStream)
213 {
214 if (serializationStream == null)
215 return null;
216
217 ICslaReader reader = CslaReaderWriterFactory.GetCslaReader();
218 var data = reader.Read(serializationStream);
219 return DeserializeAsDTO(data);
220 }
221
230 object ISerializationFormatter.Deserialize(byte[] buffer)
231 {
232 if (buffer.Length == 0)
233 return null;
234 using var serializationStream = new MemoryStream(buffer);
235 ICslaReader reader = CslaReaderWriterFactory.GetCslaReader();
236 var data = reader.Read(serializationStream);
237 return DeserializeAsDTO(data);
238 }
239
245 public object DeserializeAsDTO(List<SerializationInfo> deserialized)
246 {
247
248 _deserializationReferences = new Dictionary<int, IMobileObject>();
249 foreach (SerializationInfo info in deserialized)
250 {
251 var typeName = AssemblyNameTranslator.GetAssemblyQualifiedName(info.TypeName);
252 Type type = GetTypeFromCache(typeName);
253
254 if (type == null)
255 {
256 throw new SerializationException(string.Format(
258 }
259 else if (type == typeof(NullPlaceholder))
260 {
261 _deserializationReferences.Add(info.ReferenceId, null);
262 }
263 else
264 {
265 if (type.Equals(typeof(Security.CslaClaimsPrincipal)))
266 {
267 var state = info.GetValue<byte[]>("s");
268 using (var buffer = new System.IO.MemoryStream(state))
269 {
270 using (var reader = new System.IO.BinaryReader(buffer))
271 {
272 IMobileObject mobile = (IMobileObject)new Security.CslaClaimsPrincipal(reader);
273 _deserializationReferences.Add(info.ReferenceId, mobile);
274 }
275 }
276 }
277 else
278 {
279 IMobileObject mobile = (IMobileObject)Activator.CreateInstance(type);
280
281 _deserializationReferences.Add(info.ReferenceId, mobile);
282
283 ConvertEnumsFromIntegers(info);
284 mobile.SetState(info);
285 }
286 }
287 }
288
289 foreach (SerializationInfo info in deserialized)
290 {
291 IMobileObject mobile = _deserializationReferences[info.ReferenceId];
292
293 if (mobile != null)
294 {
295 mobile.SetChildren(info, this);
296 }
297 }
298
299 foreach (SerializationInfo info in deserialized)
300 {
301 ISerializationNotification notifiable = _deserializationReferences[info.ReferenceId] as ISerializationNotification;
302 if (notifiable != null)
303 notifiable.Deserialized();
304 }
305 return (_deserializationReferences.Count > 0 ? _deserializationReferences[1] : null);
306 }
307
313 private static void ConvertEnumsFromIntegers(SerializationInfo serializationInfo)
314 {
315 foreach (SerializationInfo.FieldData fieldData in serializationInfo.Values.Values)
316 {
317 if (!String.IsNullOrEmpty(fieldData.EnumTypeName))
318 {
319 Type enumType = MethodCaller.GetType(fieldData.EnumTypeName);
320 fieldData.Value = Enum.ToObject(enumType, fieldData.Value);
321 }
322 }
323 }
324
331 public IMobileObject GetObject(int referenceId)
332 {
333 return _deserializationReferences[referenceId];
334 }
335
336#endregion
337
338#region Static Helpers
339
348 public static byte[] Serialize(object obj)
349 {
350 using (var buffer = new System.IO.MemoryStream())
351 {
352 var formatter = new MobileFormatter();
353 formatter.Serialize(buffer, obj);
354 return buffer.ToArray();
355 }
356 }
357
366 public static List<SerializationInfo> SerializeToDTO(object obj)
367 {
368 var formatter = new MobileFormatter();
369 return formatter.SerializeAsDTO(obj);
370 }
371
377 public static object DeserializeFromDTO(List<SerializationInfo> serialized)
378 {
379 var formatter = new MobileFormatter();
380 return formatter.DeserializeAsDTO(serialized);
381 }
382
395 public static object Deserialize(byte[] data)
396 {
397 if (data == null)
398 return null;
399
400 using (var buffer = new System.IO.MemoryStream(data))
401 {
402 var formatter = new MobileFormatter();
403 return formatter.Deserialize(buffer);
404 }
405 }
406
419 public static object Deserialize(List<SerializationInfo> data)
420 {
421 if (data == null)
422 return null;
423
424 var formatter = new MobileFormatter();
425 return formatter.DeserializeAsDTO(data);
426 }
427#endregion
428
429 }
430}
A strongly-typed resource class, for looking up localized strings, etc.
static string MobileFormatterUnableToDeserialize
Looks up a localized string similar to The Type '{0}' was unable to be deserialized,...
static string MustImplementIMobileObject
Looks up a localized string similar to Type {0} must implement IMobileObject.
static string ObjectNotSerializableFormatted
Looks up a localized string similar to Object not serializable ({0}).
Serializes and deserializes objects at the field level.
IMobileObject GetObject(int referenceId)
Gets a deserialized object based on the object's reference id within the serialization stream.
List< SerializationInfo > SerializeAsDTO(object graph)
Serialize an object graph into DTO.
object Deserialize(Stream serializationStream)
Deserialize an object from XML.
object DeserializeAsDTO(List< SerializationInfo > deserialized)
Deserialize an object from DTO graph.
static object DeserializeFromDTO(List< SerializationInfo > serialized)
Serializes an object from a DTO graph
SerializationInfo SerializeObject(object obj)
Serializes an object into a SerializationInfo object.
static byte[] Serialize(object obj)
Serializes the object into a byte array.
static object Deserialize(byte[] data)
Deserializes a byte stream into an object.
void Serialize(Stream serializationStream, object graph)
Serialize an object graph into XML.
static List< SerializationInfo > SerializeToDTO(object obj)
Serializes the object into a DTO.
static object Deserialize(List< SerializationInfo > data)
Deserializes a byte stream into an object.
Placeholder for null child objects.
Implements an equality comparer for IMobileObject that compares the objects only on the basis is the ...
Object that contains information about a single field.
Object containing the serialization data for a specific object.
Dictionary< string, FieldData > Values
Dictionary containg field data.
int ReferenceId
Reference number for this object.
string TypeName
Assembly-qualified type name of the object being serialized.
Defines an object that can serialize and deserialize object graphs.
void Serialize(System.IO.Stream serializationStream, object graph)
Converts an object graph into a byte stream.
object Deserialize(System.IO.Stream serializationStream)
Converts a serialization stream into an object graph.
Represents a reader class that can be used to read the data sent across the wire in byte array format...
Definition: ICslaReader.cs:12
List< SerializationInfo > Read(Stream serializationStream)
Read the data from a stream and return a list of SerializationInfo objects
Represents a class that can be used to write a list of SerializationInfo objects into a stream,...
Definition: ICslaWriter.cs:12
void Write(Stream serializationStream, List< SerializationInfo > objectData)
Write a list of SerializationInfo objects into a stream, typically MemoryStream
Interface to be implemented by any object that supports serialization by the SerializationFormatterFa...
void SetChildren(SerializationInfo info, MobileFormatter formatter)
Method called by MobileFormatter when an object should deserialize its child references.
void SetState(SerializationInfo info)
Method called by MobileFormatter when an object should be deserialized.
Interface defining callback methods used by the SerializationFormatterFactory.GetFormatter().
void Deserialized()
Method called on an object after deserialization is complete.