Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Dispatcher / DataContractSerializerOperationFormatter.cs / 1 / DataContractSerializerOperationFormatter.cs
//------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{
using System.Collections;
using System.ServiceModel.Channels;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Runtime.Serialization;
using System.Reflection;
using System.Xml;
using System.ServiceModel.Diagnostics;
static class DataContractSerializerDefaults
{
internal const bool IgnoreExtensionDataObject = false;
internal const int MaxItemsInObjectGraph = 64 * 1024;
internal static DataContractSerializer CreateSerializer(Type type, int maxItems)
{
return CreateSerializer(type, null, maxItems);
}
internal static DataContractSerializer CreateSerializer(Type type, IList knownTypes, int maxItems)
{
return new DataContractSerializer(
type,
knownTypes,
maxItems,
DataContractSerializerDefaults.IgnoreExtensionDataObject,
false/*preserveObjectReferences*/,
null/*dataContractSurrage*/);
}
internal static DataContractSerializer CreateSerializer(Type type, string rootName, string rootNs, int maxItems)
{
return CreateSerializer(type, null, rootName, rootNs, maxItems);
}
internal static DataContractSerializer CreateSerializer(Type type, IList knownTypes, string rootName, string rootNs, int maxItems)
{
return new DataContractSerializer(
type,
rootName,
rootNs,
knownTypes,
maxItems,
DataContractSerializerDefaults.IgnoreExtensionDataObject,
false/*preserveObjectReferences*/,
null/*dataContractSurrage*/);
}
internal static DataContractSerializer CreateSerializer(Type type, XmlDictionaryString rootName, XmlDictionaryString rootNs, int maxItems)
{
return CreateSerializer(type, null, rootName, rootNs, maxItems);
}
internal static DataContractSerializer CreateSerializer(Type type, IList knownTypes, XmlDictionaryString rootName, XmlDictionaryString rootNs, int maxItems)
{
return new DataContractSerializer(
type,
rootName,
rootNs,
knownTypes,
maxItems,
DataContractSerializerDefaults.IgnoreExtensionDataObject,
false/*preserveObjectReferences*/,
null/*dataContractSurrage*/);
}
}
class DataContractSerializerOperationFormatter : OperationFormatter
{
protected MessageInfo requestMessageInfo;
protected MessageInfo replyMessageInfo;
IList knownTypes;
XsdDataContractExporter dataContractExporter;
DataContractSerializerOperationBehavior serializerFactory;
public DataContractSerializerOperationFormatter(OperationDescription description, DataContractFormatAttribute dataContractFormatAttribute,
DataContractSerializerOperationBehavior serializerFactory)
: base(description, dataContractFormatAttribute.Style == OperationFormatStyle.Rpc, false/*isEncoded*/)
{
if (description == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("description");
this.serializerFactory = serializerFactory ?? new DataContractSerializerOperationBehavior(description);
foreach (Type type in description.KnownTypes)
{
if (knownTypes == null)
knownTypes = new List();
if (type == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxKnownTypeNull, description.Name)));
ValidateDataContractType(type);
knownTypes.Add(type);
}
requestMessageInfo = CreateMessageInfo(dataContractFormatAttribute, RequestDescription, this.serializerFactory);
if (ReplyDescription != null)
replyMessageInfo = CreateMessageInfo(dataContractFormatAttribute, ReplyDescription, this.serializerFactory);
}
MessageInfo CreateMessageInfo(DataContractFormatAttribute dataContractFormatAttribute,
MessageDescription messageDescription, DataContractSerializerOperationBehavior serializerFactory)
{
if (messageDescription.IsUntypedMessage)
return null;
MessageInfo messageInfo = new MessageInfo();
MessageBodyDescription body = messageDescription.Body;
if (body.WrapperName != null)
{
messageInfo.WrapperName = AddToDictionary(body.WrapperName);
messageInfo.WrapperNamespace = AddToDictionary(body.WrapperNamespace);
}
MessagePartDescriptionCollection parts = body.Parts;
messageInfo.BodyParts = new PartInfo[parts.Count];
for (int i = 0; i < parts.Count; i++)
messageInfo.BodyParts[i] = CreatePartInfo(parts[i], dataContractFormatAttribute.Style, serializerFactory);
if (IsValidReturnValue(messageDescription.Body.ReturnValue))
messageInfo.ReturnPart = CreatePartInfo(messageDescription.Body.ReturnValue, dataContractFormatAttribute.Style, serializerFactory);
messageInfo.HeaderDescriptionTable = new MessageHeaderDescriptionTable();
messageInfo.HeaderParts = new PartInfo[messageDescription.Headers.Count];
for (int i = 0; i < messageDescription.Headers.Count;i++ )
{
MessageHeaderDescription headerDescription = messageDescription.Headers[i];
if (headerDescription.IsUnknownHeaderCollection)
messageInfo.UnknownHeaderDescription = headerDescription;
else
{
ValidateDataContractType(headerDescription.Type);
messageInfo.HeaderDescriptionTable.Add(headerDescription.Name, headerDescription.Namespace, headerDescription);
}
messageInfo.HeaderParts[i] = CreatePartInfo(headerDescription, OperationFormatStyle.Document, serializerFactory);
}
messageInfo.AnyHeaders = messageInfo.UnknownHeaderDescription != null || messageInfo.HeaderDescriptionTable.Count > 0;
return messageInfo;
}
private void ValidateDataContractType(Type type)
{
if (dataContractExporter == null)
{
dataContractExporter = new XsdDataContractExporter();
if (serializerFactory != null && serializerFactory.DataContractSurrogate != null)
{
ExportOptions options = new ExportOptions();
options.DataContractSurrogate = serializerFactory.DataContractSurrogate;
dataContractExporter.Options = options;
}
}
dataContractExporter.GetSchemaTypeName(type);//Throws if the type is not a valid data contract
}
PartInfo CreatePartInfo(MessagePartDescription part, OperationFormatStyle style, DataContractSerializerOperationBehavior serializerFactory)
{
ValidateDataContractType(part.Type);
string ns = (style == OperationFormatStyle.Rpc || part.Namespace == null) ? string.Empty : part.Namespace;
return new PartInfo(part, AddToDictionary(part.Name), AddToDictionary(ns), knownTypes, serializerFactory);
}
protected override void AddHeadersToMessage(Message message, MessageDescription messageDescription, object[] parameters, bool isRequest)
{
MessageInfo messageInfo = isRequest ? requestMessageInfo : replyMessageInfo;
PartInfo[] headerParts = messageInfo.HeaderParts;
if (headerParts == null || headerParts.Length == 0)
return;
MessageHeaders headers = message.Headers;
for (int i = 0; i < headerParts.Length; i++)
{
PartInfo headerPart = headerParts[i];
MessageHeaderDescription headerDescription = (MessageHeaderDescription)headerPart.Description;
object headerValue = parameters[headerDescription.Index];
if (headerDescription.Multiple)
{
if (headerValue != null)
{
bool isXmlElement = headerDescription.Type == typeof(XmlElement);
foreach (object headerItemValue in (IEnumerable)headerValue)
AddMessageHeaderForParameter(headers, headerPart, message.Version, headerItemValue, isXmlElement);
}
}
else
AddMessageHeaderForParameter(headers, headerPart, message.Version, headerValue, false/*isXmlElement*/);
}
}
void AddMessageHeaderForParameter(MessageHeaders headers, PartInfo headerPart, MessageVersion messageVersion, object parameterValue, bool isXmlElement)
{
string actor;
bool mustUnderstand;
bool relay;
MessageHeaderDescription headerDescription = (MessageHeaderDescription)headerPart.Description;
object valueToSerialize = GetContentOfMessageHeaderOfT(headerDescription, parameterValue, out mustUnderstand, out relay, out actor);
if (isXmlElement)
{
if (valueToSerialize == null)
return;
XmlElement xmlElement = (XmlElement)valueToSerialize;
headers.Add(new XmlElementMessageHeader(this, messageVersion, xmlElement.LocalName, xmlElement.NamespaceURI, mustUnderstand, actor, relay, xmlElement));
return;
}
headers.Add(new DataContractSerializerMessageHeader(headerPart, valueToSerialize, mustUnderstand, actor, relay));
}
protected override void SerializeBody(XmlDictionaryWriter writer, MessageVersion version, string action, MessageDescription messageDescription, object returnValue, object[] parameters, bool isRequest)
{
if(writer == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("writer"));
if(parameters == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("parameters"));
MessageInfo messageInfo;
if (isRequest)
messageInfo = requestMessageInfo;
else
messageInfo = replyMessageInfo;
if (messageInfo.WrapperName != null)
writer.WriteStartElement(messageInfo.WrapperName, messageInfo.WrapperNamespace);
if (messageInfo.ReturnPart != null)
SerializeParameter(writer, messageInfo.ReturnPart, returnValue);
SerializeParameters(writer, messageInfo.BodyParts, parameters);
if (messageInfo.WrapperName != null)
writer.WriteEndElement();
}
void SerializeParameters(XmlDictionaryWriter writer, PartInfo[] parts, object[] parameters)
{
for (int i = 0; i < parts.Length; i++)
{
PartInfo part = parts[i];
object graph = parameters[part.Description.Index];
SerializeParameter(writer, part, graph);
}
}
void SerializeParameter(XmlDictionaryWriter writer, PartInfo part, object graph)
{
if (part.Description.Multiple)
{
if (graph != null)
{
foreach (object item in (IEnumerable)graph)
SerializeParameterPart(writer, part, item);
}
}
else
SerializeParameterPart(writer, part, graph);
}
void SerializeParameterPart(XmlDictionaryWriter writer, PartInfo part, object graph)
{
try
{
part.Serializer.WriteObject(writer, graph);
}
catch (SerializationException sx)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(
SR.GetString(SR.SFxInvalidMessageBodyErrorSerializingParameter, part.Description.Namespace, part.Description.Name, sx.Message), sx));
}
}
protected override void GetHeadersFromMessage(Message message, MessageDescription messageDescription, object[] parameters, bool isRequest)
{
MessageInfo messageInfo = isRequest ? requestMessageInfo : replyMessageInfo;
if (!messageInfo.AnyHeaders)
return;
MessageHeaders headers = message.Headers;
KeyValuePair[] multipleHeaderValues = null;
ArrayList elementList = null;
if (messageInfo.UnknownHeaderDescription != null)
elementList = new ArrayList();
for(int i = 0; i < headers.Count; i++)
{
MessageHeaderInfo header = headers[i];
MessageHeaderDescription headerDescription = messageInfo.HeaderDescriptionTable.Get(header.Name, header.Namespace);
if(headerDescription != null)
{
if(header.MustUnderstand)
headers.UnderstoodHeaders.Add(header);
object item = null;
XmlDictionaryReader headerReader = headers.GetReaderAtHeader(i);
try
{
object dataValue = DeserializeHeaderContents(headerReader, message.Version, headerDescription);
if (headerDescription.TypedHeader)
item = TypedHeaderManager.Create(headerDescription.Type, dataValue, headers[i].MustUnderstand, headers[i].Relay, headers[i].Actor);
else
item = dataValue;
}
finally
{
headerReader.Close();
}
if(headerDescription.Multiple)
{
if(multipleHeaderValues == null)
multipleHeaderValues = new KeyValuePair[parameters.Length];
if(multipleHeaderValues[headerDescription.Index].Key == null)
{
multipleHeaderValues[headerDescription.Index] = new KeyValuePair(headerDescription.TypedHeader ? TypedHeaderManager.GetMessageHeaderType(headerDescription.Type) : headerDescription.Type, new ArrayList());
}
multipleHeaderValues[headerDescription.Index].Value.Add(item);
}
else
parameters[headerDescription.Index] = item;
}
else if(messageInfo.UnknownHeaderDescription != null)
{
MessageHeaderDescription unknownHeaderDescription = messageInfo.UnknownHeaderDescription;
XmlDictionaryReader headerReader = headers.GetReaderAtHeader(i);
try
{
XmlDocument doc = new XmlDocument();
object dataValue = doc.ReadNode(headerReader);
if (dataValue != null && unknownHeaderDescription.TypedHeader)
dataValue = TypedHeaderManager.Create(unknownHeaderDescription.Type, dataValue, headers[i].MustUnderstand, headers[i].Relay, headers[i].Actor);
elementList.Add(dataValue);
}
finally
{
headerReader.Close();
}
}
}
if(multipleHeaderValues != null)
{
for(int i=0;i) : typeof(XmlElement));
}
object DeserializeHeaderContents(XmlDictionaryReader reader, MessageVersion version, MessageHeaderDescription headerDescription)
{
XmlObjectSerializer serializerLocal = serializerFactory.CreateSerializer(headerDescription.Type, headerDescription.Name, headerDescription.Namespace, this.knownTypes);
return serializerLocal.ReadObject(reader);
}
protected override object DeserializeBody(XmlDictionaryReader reader, MessageVersion version, string action, MessageDescription messageDescription, object[] parameters, bool isRequest)
{
if(reader == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("reader"));
if(parameters == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("parameters"));
MessageInfo messageInfo;
if (isRequest)
messageInfo = requestMessageInfo;
else
messageInfo = replyMessageInfo;
if (messageInfo.WrapperName != null)
{
if (!reader.IsStartElement(messageInfo.WrapperName, messageInfo.WrapperNamespace))
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.GetString(SR.SFxInvalidMessageBody, messageInfo.WrapperName, messageInfo.WrapperNamespace, reader.NodeType, reader.Name, reader.NamespaceURI)));
bool isEmptyElement = reader.IsEmptyElement;
reader.Read();
if (isEmptyElement)
return null;
}
object returnValue = null;
if (messageInfo.ReturnPart != null)
{
while (true)
{
PartInfo part = messageInfo.ReturnPart;
if (part.Serializer.IsStartObject(reader))
{
returnValue = DeserializeParameter(reader, part, isRequest);
break;
}
if (!reader.IsStartElement())
break;
OperationFormatter.TraceAndSkipElement(reader);
}
}
DeserializeParameters(reader, messageInfo.BodyParts, parameters, isRequest);
if (messageInfo.WrapperName != null)
reader.ReadEndElement();
return returnValue;
}
void DeserializeParameters(XmlDictionaryReader reader, PartInfo[] parts, object[] parameters, bool isRequest)
{
int nextPartIndex = 0;
while (reader.IsStartElement())
{
for (int i = nextPartIndex; i < parts.Length; i++)
{
PartInfo part = parts[i];
if (part.Serializer.IsStartObject(reader))
{
object parameterValue = DeserializeParameter(reader, part, isRequest);
parameters[part.Description.Index] = parameterValue;
nextPartIndex = i+1;
}
else
parameters[part.Description.Index] = null;
}
if (reader.IsStartElement())
OperationFormatter.TraceAndSkipElement(reader);
}
}
object DeserializeParameter(XmlDictionaryReader reader, PartInfo part, bool isRequest)
{
if (part.Description.Multiple)
{
ArrayList items = new ArrayList();
while (part.Serializer.IsStartObject(reader))
items.Add(DeserializeParameterPart(reader, part, isRequest));
return items.ToArray(part.Description.Type);
}
return DeserializeParameterPart(reader, part, isRequest);
}
object DeserializeParameterPart(XmlDictionaryReader reader, PartInfo part, bool isRequest)
{
XmlObjectSerializer serializer = part.Serializer;
object val;
try
{
val = serializer.ReadObject(reader, false /*verifyObjectName*/);
}
catch (System.InvalidOperationException e)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
SR.GetString(SR.SFxInvalidMessageBodyErrorDeserializingParameter, part.Description.Namespace, part.Description.Name), e));
}
catch (System.Runtime.Serialization.InvalidDataContractException e)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(
SR.GetString(SR.SFxInvalidMessageBodyErrorDeserializingParameter, part.Description.Namespace, part.Description.Name), e));
}
catch (System.FormatException e)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
OperationFormatter.CreateDeserializationFailedFault(
SR.GetString(SR.SFxInvalidMessageBodyErrorDeserializingParameterMore,
part.Description.Namespace, part.Description.Name, e.Message)
, e));
}
catch (System.Runtime.Serialization.SerializationException e)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
OperationFormatter.CreateDeserializationFailedFault(
SR.GetString(SR.SFxInvalidMessageBodyErrorDeserializingParameterMore,
part.Description.Namespace, part.Description.Name, e.Message)
, e));
}
return val;
}
class DataContractSerializerMessageHeader : XmlObjectSerializerHeader
{
PartInfo headerPart;
public DataContractSerializerMessageHeader(PartInfo headerPart, object headerValue, bool mustUnderstand, string actor, bool relay)
: base(headerPart.DictionaryName.Value, headerPart.DictionaryNamespace.Value, headerValue, headerPart.Serializer, mustUnderstand, actor??string.Empty, relay)
{
this.headerPart = headerPart;
}
protected override void OnWriteStartHeader(XmlDictionaryWriter writer, MessageVersion messageVersion)
{
//Prefix needed since there may be xsi:type attribute at toplevel with qname value where ns = ""
string prefix = (this.Namespace == null || this.Namespace.Length == 0) ? string.Empty : "h";
writer.WriteStartElement(prefix, headerPart.DictionaryName, headerPart.DictionaryNamespace);
WriteHeaderAttributes(writer, messageVersion);
}
}
protected class MessageInfo
{
internal PartInfo[] HeaderParts;
internal XmlDictionaryString WrapperName;
internal XmlDictionaryString WrapperNamespace;
internal PartInfo[] BodyParts;
internal PartInfo ReturnPart;
internal MessageHeaderDescriptionTable HeaderDescriptionTable;
internal MessageHeaderDescription UnknownHeaderDescription;
internal bool AnyHeaders;
}
protected class PartInfo
{
XmlDictionaryString dictionaryName;
XmlDictionaryString dictionaryNamespace;
MessagePartDescription description;
XmlObjectSerializer serializer;
IList knownTypes;
DataContractSerializerOperationBehavior serializerFactory;
public PartInfo(MessagePartDescription description, XmlDictionaryString dictionaryName, XmlDictionaryString dictionaryNamespace,
IList knownTypes, DataContractSerializerOperationBehavior behavior)
{
this.dictionaryName = dictionaryName;
this.dictionaryNamespace = dictionaryNamespace;
this.description = description;
this.knownTypes = knownTypes;
this.serializerFactory = behavior;
}
public MessagePartDescription Description
{
get { return description; }
}
public XmlDictionaryString DictionaryName
{
get { return dictionaryName; }
}
public XmlDictionaryString DictionaryNamespace
{
get { return dictionaryNamespace; }
}
public XmlObjectSerializer Serializer
{
get
{
if (serializer == null)
serializer = serializerFactory.CreateSerializer(description.Type, DictionaryName, DictionaryNamespace, knownTypes);
return serializer;
}
}
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- FontInfo.cs
- XmlSchemaSimpleContent.cs
- DataSourceNameHandler.cs
- EventLogStatus.cs
- DataPointer.cs
- ClientConfigurationHost.cs
- DetailsViewPagerRow.cs
- CustomAttributeBuilder.cs
- SerialErrors.cs
- XsltOutput.cs
- ToolStripDropDownButton.cs
- XamlRtfConverter.cs
- SiblingIterators.cs
- ContentElementCollection.cs
- AssemblyName.cs
- XmlArrayAttribute.cs
- SudsParser.cs
- SqlFunctionAttribute.cs
- Journaling.cs
- MediaElementAutomationPeer.cs
- SqlClientMetaDataCollectionNames.cs
- AxHost.cs
- AutomationPatternInfo.cs
- MetadataUtilsSmi.cs
- OutKeywords.cs
- Behavior.cs
- MenuItemStyleCollectionEditor.cs
- CodeAccessSecurityEngine.cs
- APCustomTypeDescriptor.cs
- CurrentChangingEventArgs.cs
- GetPageCompletedEventArgs.cs
- UIPropertyMetadata.cs
- UpDownEvent.cs
- SessionParameter.cs
- UIAgentInitializationException.cs
- MessageSecurityProtocolFactory.cs
- BindToObject.cs
- Converter.cs
- ConnectionStringSettings.cs
- SqlDataSourceCache.cs
- MonitoringDescriptionAttribute.cs
- SafeSecurityHelper.cs
- DbUpdateCommandTree.cs
- PropertyTab.cs
- CircleEase.cs
- DataBoundControlAdapter.cs
- Model3DGroup.cs
- HitTestParameters.cs
- DetailsViewRowCollection.cs
- UIElementIsland.cs
- TextProperties.cs
- CharAnimationUsingKeyFrames.cs
- RequestQueue.cs
- TreeChangeInfo.cs
- RangeValidator.cs
- XmlQueryOutput.cs
- PerfCounterSection.cs
- HtmlString.cs
- Perspective.cs
- StrokeCollection.cs
- _SafeNetHandles.cs
- DataGridViewRowHeaderCell.cs
- ItemAutomationPeer.cs
- VectorAnimationBase.cs
- PanelDesigner.cs
- StaticExtensionConverter.cs
- Exceptions.cs
- XmlNullResolver.cs
- GradientStop.cs
- mediaeventargs.cs
- DataRowComparer.cs
- XPathDocumentIterator.cs
- ObjectDataSourceStatusEventArgs.cs
- ActivationServices.cs
- SatelliteContractVersionAttribute.cs
- SqlTriggerContext.cs
- StyleBamlRecordReader.cs
- PackageProperties.cs
- CellLabel.cs
- HttpDebugHandler.cs
- AssemblyName.cs
- PerformanceCounterLib.cs
- LifetimeManager.cs
- CurrentChangedEventManager.cs
- RevocationPoint.cs
- CustomDictionarySources.cs
- Library.cs
- CompositeActivityMarkupSerializer.cs
- OutputScopeManager.cs
- MethodBuilder.cs
- TableCell.cs
- AutoGeneratedFieldProperties.cs
- RemoteWebConfigurationHost.cs
- DbInsertCommandTree.cs
- SubtreeProcessor.cs
- RadioButtonFlatAdapter.cs
- PresentationTraceSources.cs
- WSAddressing10ProblemHeaderQNameFault.cs
- ExpandSegmentCollection.cs
- TextTreeTextElementNode.cs