CSLA.NET 6.0.0
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 private ApplicationContext ApplicationContext { get; set; }
28
33 public MobileFormatter(ApplicationContext applicationContext)
34 {
35 ApplicationContext = applicationContext;
36 }
37
38 #region Serialize
39
51 public void Serialize(Stream serializationStream, object graph)
52 {
53 ICslaWriter writer = CslaReaderWriterFactory.GetCslaWriter(ApplicationContext);
54 writer.Write(serializationStream, SerializeToDTO(graph));
55 }
56
61 byte[] ISerializationFormatter.Serialize(object graph)
62 {
63 using var buffer = new MemoryStream();
64 Serialize(buffer, graph);
65 buffer.Position = 0;
66 return buffer.ToArray();
67 }
68
76 public List<SerializationInfo> SerializeAsDTO(object graph)
77 {
78 _serializationReferences.Clear();
79
80 SerializeObject(graph);
81
82 ConvertEnumsToIntegers();
83 List<SerializationInfo> serialized = _serializationReferences.Values.ToList();
84
85 return serialized;
86 }
87
103 private void ConvertEnumsToIntegers()
104 {
105 foreach (SerializationInfo serializationInfo in _serializationReferences.Values)
106 {
107 foreach (SerializationInfo.FieldData fieldData in serializationInfo.Values.Values)
108 {
109 if (fieldData.Value != null)
110 {
111 Type fieldType = fieldData.Value.GetType();
112
113 if (fieldType.IsEnum)
114 {
115 fieldData.Value = Convert.ChangeType(fieldData.Value, Enum.GetUnderlyingType(fieldType));
116 fieldData.EnumTypeName = fieldType.AssemblyQualifiedName;
117 }
118 }
119 }
120 }
121 }
122
129 {
131 if (obj == null)
132 {
133 NullPlaceholder nullPlaceholder = new NullPlaceholder();
134
135 info = new SerializationInfo(_serializationReferences.Count + 1);
136 _serializationReferences.Add(nullPlaceholder, info);
137
138 info.TypeName = AssemblyNameTranslator.GetAssemblyQualifiedName(typeof(NullPlaceholder));
139 }
140 else
141 {
142 var thisType = obj.GetType();
143 if (obj is System.Security.Claims.ClaimsPrincipal cp)
144 {
145 obj = new Security.CslaClaimsPrincipal(cp);
146 thisType = obj.GetType();
147 }
148 if (!thisType.IsSerializable)
149 throw new InvalidOperationException(
150 string.Format(Resources.ObjectNotSerializableFormatted, thisType.FullName));
151 if (!(obj is IMobileObject mobile))
152 throw new InvalidOperationException(
154 thisType.Name));
155
156 if (!_serializationReferences.TryGetValue(mobile, out info))
157 {
158 info = new SerializationInfo(_serializationReferences.Count + 1);
159 _serializationReferences.Add(mobile, info);
160
161 info.TypeName = AssemblyNameTranslator.GetAssemblyQualifiedName(thisType);
162 if (thisType.Equals(typeof(Security.CslaClaimsPrincipal)))
163 {
164 var principal = (Security.CslaClaimsPrincipal)obj;
165 using (var buffer = new System.IO.MemoryStream())
166 {
167 using (var writer = new System.IO.BinaryWriter(buffer))
168 {
169 principal.WriteTo(writer);
170 info.AddValue("s", buffer.ToArray());
171 }
172 }
173 }
174 else
175 {
176 mobile.GetChildren(info, this);
177 mobile.GetState(info);
178 }
179 }
180 }
181 return info;
182 }
183
184 private Dictionary<IMobileObject, SerializationInfo> _serializationReferences =
185 new Dictionary<IMobileObject, SerializationInfo>(new ReferenceComparer<IMobileObject>());
186
187#endregion
188
189#region Deserialize
190
191 private Dictionary<int, IMobileObject> _deserializationReferences =
192 new Dictionary<int, IMobileObject>();
193
194 private Dictionary<string, Type> _typeCache = new Dictionary<string, Type>();
195
196 private Type GetTypeFromCache(string typeName)
197 {
198 Type result;
199 if (!_typeCache.TryGetValue(typeName, out result))
200 {
201 result = Csla.Reflection.MethodCaller.GetType(typeName);
202
203 if (result == null)
204 {
205 throw new SerializationException(string.Format(
207 typeName));
208 }
209 _typeCache.Add(typeName, result);
210 }
211
212 return result;
213 }
214
223 public object Deserialize(Stream serializationStream)
224 {
225 if (serializationStream == null)
226 return null;
227
228 ICslaReader reader = CslaReaderWriterFactory.GetCslaReader(ApplicationContext);
229 var data = reader.Read(serializationStream);
230 return DeserializeAsDTO(data);
231 }
232
241 object ISerializationFormatter.Deserialize(byte[] buffer)
242 {
243 if (buffer.Length == 0)
244 return null;
245 using var serializationStream = new MemoryStream(buffer);
246 ICslaReader reader = CslaReaderWriterFactory.GetCslaReader(ApplicationContext);
247 var data = reader.Read(serializationStream);
248 return DeserializeAsDTO(data);
249 }
250
256 public object DeserializeAsDTO(List<SerializationInfo> deserialized)
257 {
258
259 _deserializationReferences = new Dictionary<int, IMobileObject>();
260 foreach (SerializationInfo info in deserialized)
261 {
262 var typeName = AssemblyNameTranslator.GetAssemblyQualifiedName(info.TypeName);
263 Type type = GetTypeFromCache(typeName);
264
265 if (type == null)
266 {
267 throw new SerializationException(string.Format(
269 }
270 else if (type == typeof(NullPlaceholder))
271 {
272 _deserializationReferences.Add(info.ReferenceId, null);
273 }
274 else
275 {
276 if (type.Equals(typeof(Security.CslaClaimsPrincipal)))
277 {
278 var state = info.GetValue<byte[]>("s");
279 using (var buffer = new System.IO.MemoryStream(state))
280 {
281 using (var reader = new System.IO.BinaryReader(buffer))
282 {
283 IMobileObject mobile = (IMobileObject)new Security.CslaClaimsPrincipal(reader);
284 _deserializationReferences.Add(info.ReferenceId, mobile);
285 }
286 }
287 }
288 else
289 {
291
292 _deserializationReferences.Add(info.ReferenceId, mobile);
293
294 ConvertEnumsFromIntegers(info);
295 mobile.SetState(info);
296 }
297 }
298 }
299
300 foreach (SerializationInfo info in deserialized)
301 {
302 IMobileObject mobile = _deserializationReferences[info.ReferenceId];
303
304 if (mobile != null)
305 {
306 mobile.SetChildren(info, this);
307 }
308 }
309
310 foreach (SerializationInfo info in deserialized)
311 {
312 ISerializationNotification notifiable = _deserializationReferences[info.ReferenceId] as ISerializationNotification;
313 if (notifiable != null)
314 notifiable.Deserialized();
315 }
316 return (_deserializationReferences.Count > 0 ? _deserializationReferences[1] : null);
317 }
318
324 private static void ConvertEnumsFromIntegers(SerializationInfo serializationInfo)
325 {
326 foreach (SerializationInfo.FieldData fieldData in serializationInfo.Values.Values)
327 {
328 if (!String.IsNullOrEmpty(fieldData.EnumTypeName))
329 {
330 Type enumType = MethodCaller.GetType(fieldData.EnumTypeName);
331 fieldData.Value = Enum.ToObject(enumType, fieldData.Value);
332 }
333 }
334 }
335
342 public IMobileObject GetObject(int referenceId)
343 {
344 return _deserializationReferences[referenceId];
345 }
346
347#endregion
348
349#region Helpers
350
359 public byte[] SerializeToByteArray(object obj)
360 {
361 using (var buffer = new System.IO.MemoryStream())
362 {
363 var formatter = new MobileFormatter(ApplicationContext);
364 formatter.Serialize(buffer, obj);
365 return buffer.ToArray();
366 }
367 }
368
377 public List<SerializationInfo> SerializeToDTO(object obj)
378 {
379 var formatter = new MobileFormatter(ApplicationContext);
380 return formatter.SerializeAsDTO(obj);
381 }
382
388 public object DeserializeFromDTO(List<SerializationInfo> serialized)
389 {
390 var formatter = new MobileFormatter(ApplicationContext);
391 return formatter.DeserializeAsDTO(serialized);
392 }
393
406 public object DeserializeFromByteArray(byte[] data)
407 {
408 if (data == null)
409 return null;
410
411 using (var buffer = new System.IO.MemoryStream(data))
412 {
413 var formatter = new MobileFormatter(ApplicationContext);
414 return formatter.Deserialize(buffer);
415 }
416 }
417
430 public object DeserializeFromSerializationInfo(List<SerializationInfo> data)
431 {
432 if (data == null)
433 return null;
434
435 var formatter = new MobileFormatter(ApplicationContext);
436 return formatter.DeserializeAsDTO(data);
437 }
438#endregion
439
440 }
441}
Provides consistent context information between the client and server DataPortal objects.
object CreateInstance(Type objectType, params object[] parameters)
Creates an object using Activator.
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 DeserializeFromSerializationInfo(List< SerializationInfo > data)
Deserializes a byte stream into an object.
object DeserializeFromDTO(List< SerializationInfo > serialized)
Serializes an object from a DTO graph
MobileFormatter(ApplicationContext applicationContext)
Creates an instance of the type.
object Deserialize(Stream serializationStream)
Deserialize an object from XML.
object DeserializeAsDTO(List< SerializationInfo > deserialized)
Deserialize an object from DTO graph.
byte[] SerializeToByteArray(object obj)
Serializes the object into a byte array.
List< SerializationInfo > SerializeToDTO(object obj)
Serializes the object into a DTO.
object DeserializeFromByteArray(byte[] data)
Deserializes a byte stream into an object.
SerializationInfo SerializeObject(object obj)
Serializes an object into a SerializationInfo object.
void Serialize(Stream serializationStream, object graph)
Serialize an object graph into XML.
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.