//----------------------------------------------------------------------- // // Copyright (c) Andrew Arnott. All rights reserved. // //----------------------------------------------------------------------- namespace DotNetOAuth.Messaging { using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Runtime.Serialization; using System.Xml; using System.Xml.Linq; using DotNetOAuth.Messaging.Reflection; /// /// Serializes/deserializes OAuth messages for/from transit. /// internal class MessageSerializer { /// /// The specific -derived type /// that will be serialized and deserialized using this class. /// private readonly Type messageType; /// /// Initializes a new instance of the MessageSerializer class. /// /// The specific -derived type /// that will be serialized and deserialized using this class. private MessageSerializer(Type messageType) { Debug.Assert(messageType != null, "messageType == null"); if (!typeof(IProtocolMessage).IsAssignableFrom(messageType)) { throw new ArgumentException( string.Format( CultureInfo.CurrentCulture, MessagingStrings.UnexpectedType, typeof(IProtocolMessage).FullName, messageType.FullName), "messageType"); } this.messageType = messageType; } /// /// Creates or reuses a message serializer for a given message type. /// /// The type of message that will be serialized/deserialized. /// A message serializer for the given message type. internal static MessageSerializer Get(Type messageType) { if (messageType == null) { throw new ArgumentNullException("messageType"); } return new MessageSerializer(messageType); } /// /// Reads the data from a message instance and returns a series of name=value pairs for the fields that must be included in the message. /// /// The message to be serialized. /// The dictionary of values to send for the message. internal IDictionary Serialize(IProtocolMessage message) { if (message == null) { throw new ArgumentNullException("message"); } var result = new Reflection.MessageDictionary(message); return result; } /// /// Reads name=value pairs into an OAuth message. /// /// The name=value pairs that were read in from the transport. /// The instantiated and initialized instance. internal IProtocolMessage Deserialize(IDictionary fields) { if (fields == null) { throw new ArgumentNullException("fields"); } // Before we deserialize the message, make sure all the required parts are present. MessageDescription.Get(this.messageType).EnsureRequiredMessagePartsArePresent(fields.Keys); IProtocolMessage result ; try { result = (IProtocolMessage)Activator.CreateInstance(this.messageType, true); } catch (MissingMethodException ex) { throw new ProtocolException("Failed to instantiate type " + this.messageType.FullName, ex); } foreach (var pair in fields) { IDictionary dictionary = new MessageDictionary(result); dictionary.Add(pair); } result.EnsureValidMessage(); return result; } } }