Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataWeb / Server / System / Data / Services / Serializers / PlainXmlSerializer.cs / 1305376 / PlainXmlSerializer.cs
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Provides a serializer for non-reference entities in plain XML.
//
//
// @owner [....]
//---------------------------------------------------------------------
namespace System.Data.Services.Serializers
{
#region Namespaces.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data.Services.Providers;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Xml;
#endregion Namespaces.
/// This class serializes primitive and complex type as name/value pairs.
internal sealed class PlainXmlSerializer : Serializer
{
/// Writer to which output is sent.
private XmlWriter writer;
/// Initializes a new SyndicationSerializer instance.
/// Description of request.
/// Base URI from which resources should be resolved.
/// Service with configuration and provider from which metadata should be gathered.
/// Output stream.
/// Encoding for output.
internal PlainXmlSerializer(
RequestDescription requestDescription,
Uri absoluteServiceUri,
IDataService service,
Stream output,
Encoding encoding)
: base(requestDescription, absoluteServiceUri, service, null)
{
Debug.Assert(output != null, "output != null");
Debug.Assert(encoding != null, "encoding != null");
this.writer = XmlUtil.CreateXmlWriterAndWriteProcessingInstruction(output, encoding);
}
/// Serializes exception information.
/// Description of exception to serialize.
public override void WriteException(HandleExceptionArgs args)
{
ErrorHandler.SerializeXmlError(args, this.writer);
}
/// Converts the specified value to a serializable string.
/// Non-null value to convert.
/// The specified value converted to a serializable string.
internal static string PrimitiveToString(object value)
{
Debug.Assert(value != null, "value != null");
string result;
if (!System.Data.Services.Parsing.WebConvert.TryXmlPrimitiveToString(value, out result))
{
throw new InvalidOperationException(Strings.Serializer_CannotConvertValue(value));
}
return result;
}
/// Writes a property with a null value.
/// XmlWriter to write to.
/// Property name.
/// Type name for value.
internal static void WriteNullValue(XmlWriter writer, string propertyName, string expectedTypeName)
{
Debug.Assert(writer != null, "writer != null");
Debug.Assert(propertyName != null, "propertyName != null");
Debug.Assert(expectedTypeName != null, "expectedTypeName != null");
WriteStartElementWithType(writer, propertyName, expectedTypeName);
writer.WriteAttributeString(XmlConstants.AtomNullAttributeName, XmlConstants.DataWebMetadataNamespace, XmlConstants.XmlTrueLiteral);
writer.WriteEndElement();
}
/// Writes the start tag for a property.
/// XmlWriter to write to.
/// Property name.
/// Type name for value.
internal static void WriteStartElementWithType(XmlWriter writer, string propertyName, string propertyTypeName)
{
Debug.Assert(writer != null, "writer != null");
Debug.Assert(propertyName != null, "propertyName != null");
Debug.Assert(propertyTypeName != null, "expectedType != null");
Debug.Assert(
object.ReferenceEquals(propertyTypeName, XmlConstants.EdmStringTypeName) == (propertyTypeName == XmlConstants.EdmStringTypeName),
"object equality and string equality are the same for Edm.String");
writer.WriteStartElement(propertyName, XmlConstants.DataWebNamespace);
if (!object.ReferenceEquals(propertyTypeName, XmlConstants.EdmStringTypeName))
{
writer.WriteAttributeString(XmlConstants.AtomTypeAttributeName, XmlConstants.DataWebMetadataNamespace, propertyTypeName);
}
}
/// Writes an already-formatted property.
/// XmlWriter to write to.
/// Property name.
/// Type name for value.
/// Property value in text form.
internal static void WriteTextValue(XmlWriter writer, string propertyName, string propertyTypeName, string propertyText)
{
Debug.Assert(writer != null, "writer != null");
Debug.Assert(propertyName != null, "propertyName != null");
WriteStartElementWithType(writer, propertyName, propertyTypeName);
WebUtil.WriteSpacePreserveAttributeIfNecessary(writer, propertyText);
writer.WriteString(propertyText);
writer.WriteEndElement();
}
/// Flushes the writer to the underlying stream.
protected override void Flush()
{
this.writer.Flush();
}
/// Writes a single top-level element.
/// Expandd results on the specified .
/// Element to write, possibly null.
protected override void WriteTopLevelElement(IExpandedResult expandedResult, object element)
{
Debug.Assert(
element != null || this.RequestDescription.TargetResourceType != null || this.RequestDescription.TargetKind == RequestTargetKind.OpenProperty,
"element != null || this.RequestDescription.TargetResourceType != null || this.RequestDescription.TargetKind == RequestTargetKind.OpenProperty");
Debug.Assert(
this.RequestDescription.IsSingleResult,
"this.RequestDescription.IsSingleResult -- primitive collections not currently supported");
string propertyName = this.RequestDescription.ContainerName;
ResourceType resourceType;
if (element == null)
{
if (this.RequestDescription.TargetKind == RequestTargetKind.OpenProperty)
{
resourceType = ResourceType.PrimitiveStringResourceType;
}
else
{
resourceType = this.RequestDescription.TargetResourceType;
}
}
else
{
resourceType = WebUtil.GetResourceType(this.Provider, element);
}
if (resourceType == null)
{
throw new InvalidOperationException(Strings.Serializer_UnsupportedTopLevelType(element.GetType()));
}
this.WriteValueWithName(element, propertyName, resourceType);
}
/// Writes multiple top-level elements, possibly none.
/// Expanded results for elements.
/// Enumerator for elements to write.
/// Whether was succesfully advanced to the first element.
protected override void WriteTopLevelElements(IExpandedResult expanded, IEnumerator elements, bool hasMoved)
{
Debug.Assert(
!this.RequestDescription.IsSingleResult,
"!this.RequestDescription.IsSingleResult -- otherwise WriteTopLevelElement should have been called");
this.writer.WriteStartElement(this.RequestDescription.ContainerName, XmlConstants.DataWebNamespace);
while (hasMoved)
{
object element = elements.Current;
ResourceType resourceType = element == null ?
this.RequestDescription.TargetResourceType : WebUtil.GetResourceType(this.Provider, element);
if (resourceType == null)
{
throw new InvalidOperationException(Strings.Serializer_UnsupportedTopLevelType(element.GetType()));
}
this.WriteValueWithName(element, XmlConstants.XmlCollectionItemElementName, resourceType);
hasMoved = elements.MoveNext();
}
this.writer.WriteEndElement();
}
///
/// Writes the row count.
///
protected override void WriteRowCount()
{
this.writer.WriteStartElement(
XmlConstants.DataWebMetadataNamespacePrefix,
XmlConstants.RowCountElement,
XmlConstants.DataWebMetadataNamespace);
this.writer.WriteValue(this.RequestDescription.CountValue);
this.writer.WriteEndElement();
}
///
/// Write out the uri for the given element
///
/// element whose uri needs to be written out.
protected override void WriteLink(object element)
{
Debug.Assert(element != null, "element != null");
this.IncrementSegmentResultCount();
Uri uri = Serializer.GetUri(element, this.Provider, this.CurrentContainer, this.AbsoluteServiceUri);
this.writer.WriteStartElement(XmlConstants.UriElementName, XmlConstants.DataWebNamespace);
this.writer.WriteValue(uri.AbsoluteUri);
this.writer.WriteEndElement();
}
///
/// Write out the uri for the given elements
///
/// elements whose uri need to be writtne out
/// the current state of the enumerator.
protected override void WriteLinkCollection(IEnumerator elements, bool hasMoved)
{
this.writer.WriteStartElement(XmlConstants.LinkCollectionElementName, XmlConstants.DataWebNamespace);
// write count?
if (this.RequestDescription.CountOption == RequestQueryCountOption.Inline)
{
this.WriteRowCount();
}
object lastObject = null;
IExpandedResult lastExpandedSkipToken = null;
while (hasMoved)
{
object element = elements.Current;
IExpandedResult skipToken = null;
if (element != null)
{
IExpandedResult expanded = element as IExpandedResult;
if (expanded != null)
{
element = GetExpandedElement(expanded);
skipToken = this.GetSkipToken(expanded);
}
}
this.WriteLink(element);
hasMoved = elements.MoveNext();
lastObject = element;
lastExpandedSkipToken = skipToken;
}
if (this.NeedNextPageLink(elements))
{
this.WriteNextPageLink(lastObject, lastExpandedSkipToken, this.RequestDescription.ResultUri);
}
this.writer.WriteEndElement();
}
///
/// Writes the next page link to the current xml writer corresponding to the feed
///
/// Object that will contain the keys for skip token
/// The value of the $skiptoken property of the object being written
/// Absolute URI for the result
private void WriteNextPageLink(object lastElement, IExpandedResult expandedResult, Uri absoluteUri)
{
this.writer.WriteStartElement(XmlConstants.NextElementName, XmlConstants.DataWebNamespace);
this.writer.WriteValue(this.GetNextLinkUri(lastElement, expandedResult, absoluteUri));
this.writer.WriteEndElement();
}
/// Writes all the properties of the specified resource or complex object.
/// Resource or complex object with properties to write out.
/// Resource type describing the element type.
private void WriteObjectProperties(object element, ResourceType resourceType)
{
Debug.Assert(element != null, "element != null");
Debug.Assert(resourceType != null, "resourceType != null");
foreach (ResourceProperty property in resourceType.Properties)
{
string propertyName = property.Name;
object propertyValue = WebUtil.GetPropertyValue(this.Provider, element, resourceType, property, null);
bool needPop = this.PushSegmentForProperty(property);
if (property.TypeKind == ResourceTypeKind.ComplexType)
{
this.WriteComplexObjectValue(propertyValue, propertyName, property.ResourceType);
}
else
{
Debug.Assert(property.TypeKind == ResourceTypeKind.Primitive, "property.TypeKind == ResourceTypeKind.Primitive");
this.WritePrimitiveValue(propertyValue, property.Name, property.ResourceType);
}
this.PopSegmentName(needPop);
}
if (resourceType.IsOpenType)
{
IEnumerable> properties = this.Provider.GetOpenPropertyValues(element);
foreach (KeyValuePair property in properties)
{
string propertyName = property.Key;
object value = property.Value;
if (value == null || value == DBNull.Value)
{
continue;
}
ResourceType propertyResourceType = WebUtil.GetResourceType(this.Provider, value);
if (propertyResourceType == null)
{
continue;
}
if (propertyResourceType.ResourceTypeKind == ResourceTypeKind.Primitive)
{
this.WritePrimitiveValue(value, propertyName, propertyResourceType);
}
else
{
if (propertyResourceType.ResourceTypeKind == ResourceTypeKind.ComplexType)
{
Debug.Assert(propertyResourceType.InstanceType == value.GetType(), "propertyResourceType.Type == valueType");
this.WriteComplexObjectValue(value, propertyName, propertyResourceType);
}
else
{
Debug.Assert(propertyResourceType.ResourceTypeKind == ResourceTypeKind.EntityType, "EntityType expected.");
// Open navigation properties are not supported on OpenTypes
throw DataServiceException.CreateBadRequestError(Strings.OpenNavigationPropertiesNotSupportedOnOpenTypes(propertyName));
}
}
}
}
}
/// Writes a property with a primitive value.
/// Value.
/// Property name.
/// Type for element.
private void WritePrimitiveValue(object element, string propertyName, ResourceType type)
{
Debug.Assert(propertyName != null, "propertyName != null");
Debug.Assert(type != null, "type != null");
if (element == null)
{
WriteNullValue(this.writer, propertyName, type.FullName);
return;
}
string propertyText = PrimitiveToString(element);
WriteTextValue(this.writer, propertyName, type.FullName, propertyText);
}
/// Writes the value of a complex object.
/// Element to write.
/// Property name.
/// Type for element.
private void WriteComplexObjectValue(object element, string propertyName, ResourceType expectedType)
{
Debug.Assert(!String.IsNullOrEmpty(propertyName), "!String.IsNullOrEmpty(propertyName)");
Debug.Assert(expectedType != null, "expectedType != null");
Debug.Assert(expectedType.ResourceTypeKind == ResourceTypeKind.ComplexType, "Must be complex type");
if (element == null)
{
WriteNullValue(this.writer, propertyName, expectedType.FullName);
return;
}
// Non-value complex types may form a cycle.
// PERF: we can keep a single element around and save the HashSet initialization
// until we find a second complex type - this saves the allocation on trees
// with shallow (single-level) complex types.
this.RecurseEnter();
Debug.Assert(!expectedType.InstanceType.IsValueType, "!expectedType.Type.IsValueType -- checked in the resource type constructor.");
if (this.AddToComplexTypeCollection(element))
{
ResourceType resourceType = WebUtil.GetNonPrimitiveResourceType(this.Provider, element);
WriteStartElementWithType(this.writer, propertyName, resourceType.FullName);
this.WriteObjectProperties(element, resourceType);
this.writer.WriteEndElement();
this.RemoveFromComplexTypeCollection(element);
}
else
{
throw new InvalidOperationException(Strings.Serializer_LoopsNotAllowedInComplexTypes(propertyName));
}
this.RecurseLeave();
}
/// Writes the value with the specified name.
/// Element to write out.
/// Property name for element.
/// Type of resource to write.
private void WriteValueWithName(object element, string propertyName, ResourceType resourceType)
{
Debug.Assert(propertyName != null, "propertyName != null");
Debug.Assert(resourceType != null, "resourceType != null");
if (resourceType.ResourceTypeKind == ResourceTypeKind.Primitive)
{
this.WritePrimitiveValue(element, propertyName, resourceType);
}
else
{
Debug.Assert(
resourceType.ResourceTypeKind == ResourceTypeKind.ComplexType,
"resourceType.ResourceTypeKind == ResourceTypeKind.ComplexType -- POX doesn't support " + resourceType.ResourceTypeKind);
this.WriteComplexObjectValue(element, propertyName, resourceType);
}
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Provides a serializer for non-reference entities in plain XML.
//
//
// @owner [....]
//---------------------------------------------------------------------
namespace System.Data.Services.Serializers
{
#region Namespaces.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data.Services.Providers;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Xml;
#endregion Namespaces.
/// This class serializes primitive and complex type as name/value pairs.
internal sealed class PlainXmlSerializer : Serializer
{
/// Writer to which output is sent.
private XmlWriter writer;
/// Initializes a new SyndicationSerializer instance.
/// Description of request.
/// Base URI from which resources should be resolved.
/// Service with configuration and provider from which metadata should be gathered.
/// Output stream.
/// Encoding for output.
internal PlainXmlSerializer(
RequestDescription requestDescription,
Uri absoluteServiceUri,
IDataService service,
Stream output,
Encoding encoding)
: base(requestDescription, absoluteServiceUri, service, null)
{
Debug.Assert(output != null, "output != null");
Debug.Assert(encoding != null, "encoding != null");
this.writer = XmlUtil.CreateXmlWriterAndWriteProcessingInstruction(output, encoding);
}
/// Serializes exception information.
/// Description of exception to serialize.
public override void WriteException(HandleExceptionArgs args)
{
ErrorHandler.SerializeXmlError(args, this.writer);
}
/// Converts the specified value to a serializable string.
/// Non-null value to convert.
/// The specified value converted to a serializable string.
internal static string PrimitiveToString(object value)
{
Debug.Assert(value != null, "value != null");
string result;
if (!System.Data.Services.Parsing.WebConvert.TryXmlPrimitiveToString(value, out result))
{
throw new InvalidOperationException(Strings.Serializer_CannotConvertValue(value));
}
return result;
}
/// Writes a property with a null value.
/// XmlWriter to write to.
/// Property name.
/// Type name for value.
internal static void WriteNullValue(XmlWriter writer, string propertyName, string expectedTypeName)
{
Debug.Assert(writer != null, "writer != null");
Debug.Assert(propertyName != null, "propertyName != null");
Debug.Assert(expectedTypeName != null, "expectedTypeName != null");
WriteStartElementWithType(writer, propertyName, expectedTypeName);
writer.WriteAttributeString(XmlConstants.AtomNullAttributeName, XmlConstants.DataWebMetadataNamespace, XmlConstants.XmlTrueLiteral);
writer.WriteEndElement();
}
/// Writes the start tag for a property.
/// XmlWriter to write to.
/// Property name.
/// Type name for value.
internal static void WriteStartElementWithType(XmlWriter writer, string propertyName, string propertyTypeName)
{
Debug.Assert(writer != null, "writer != null");
Debug.Assert(propertyName != null, "propertyName != null");
Debug.Assert(propertyTypeName != null, "expectedType != null");
Debug.Assert(
object.ReferenceEquals(propertyTypeName, XmlConstants.EdmStringTypeName) == (propertyTypeName == XmlConstants.EdmStringTypeName),
"object equality and string equality are the same for Edm.String");
writer.WriteStartElement(propertyName, XmlConstants.DataWebNamespace);
if (!object.ReferenceEquals(propertyTypeName, XmlConstants.EdmStringTypeName))
{
writer.WriteAttributeString(XmlConstants.AtomTypeAttributeName, XmlConstants.DataWebMetadataNamespace, propertyTypeName);
}
}
/// Writes an already-formatted property.
/// XmlWriter to write to.
/// Property name.
/// Type name for value.
/// Property value in text form.
internal static void WriteTextValue(XmlWriter writer, string propertyName, string propertyTypeName, string propertyText)
{
Debug.Assert(writer != null, "writer != null");
Debug.Assert(propertyName != null, "propertyName != null");
WriteStartElementWithType(writer, propertyName, propertyTypeName);
WebUtil.WriteSpacePreserveAttributeIfNecessary(writer, propertyText);
writer.WriteString(propertyText);
writer.WriteEndElement();
}
/// Flushes the writer to the underlying stream.
protected override void Flush()
{
this.writer.Flush();
}
/// Writes a single top-level element.
/// Expandd results on the specified .
/// Element to write, possibly null.
protected override void WriteTopLevelElement(IExpandedResult expandedResult, object element)
{
Debug.Assert(
element != null || this.RequestDescription.TargetResourceType != null || this.RequestDescription.TargetKind == RequestTargetKind.OpenProperty,
"element != null || this.RequestDescription.TargetResourceType != null || this.RequestDescription.TargetKind == RequestTargetKind.OpenProperty");
Debug.Assert(
this.RequestDescription.IsSingleResult,
"this.RequestDescription.IsSingleResult -- primitive collections not currently supported");
string propertyName = this.RequestDescription.ContainerName;
ResourceType resourceType;
if (element == null)
{
if (this.RequestDescription.TargetKind == RequestTargetKind.OpenProperty)
{
resourceType = ResourceType.PrimitiveStringResourceType;
}
else
{
resourceType = this.RequestDescription.TargetResourceType;
}
}
else
{
resourceType = WebUtil.GetResourceType(this.Provider, element);
}
if (resourceType == null)
{
throw new InvalidOperationException(Strings.Serializer_UnsupportedTopLevelType(element.GetType()));
}
this.WriteValueWithName(element, propertyName, resourceType);
}
/// Writes multiple top-level elements, possibly none.
/// Expanded results for elements.
/// Enumerator for elements to write.
/// Whether was succesfully advanced to the first element.
protected override void WriteTopLevelElements(IExpandedResult expanded, IEnumerator elements, bool hasMoved)
{
Debug.Assert(
!this.RequestDescription.IsSingleResult,
"!this.RequestDescription.IsSingleResult -- otherwise WriteTopLevelElement should have been called");
this.writer.WriteStartElement(this.RequestDescription.ContainerName, XmlConstants.DataWebNamespace);
while (hasMoved)
{
object element = elements.Current;
ResourceType resourceType = element == null ?
this.RequestDescription.TargetResourceType : WebUtil.GetResourceType(this.Provider, element);
if (resourceType == null)
{
throw new InvalidOperationException(Strings.Serializer_UnsupportedTopLevelType(element.GetType()));
}
this.WriteValueWithName(element, XmlConstants.XmlCollectionItemElementName, resourceType);
hasMoved = elements.MoveNext();
}
this.writer.WriteEndElement();
}
///
/// Writes the row count.
///
protected override void WriteRowCount()
{
this.writer.WriteStartElement(
XmlConstants.DataWebMetadataNamespacePrefix,
XmlConstants.RowCountElement,
XmlConstants.DataWebMetadataNamespace);
this.writer.WriteValue(this.RequestDescription.CountValue);
this.writer.WriteEndElement();
}
///
/// Write out the uri for the given element
///
/// element whose uri needs to be written out.
protected override void WriteLink(object element)
{
Debug.Assert(element != null, "element != null");
this.IncrementSegmentResultCount();
Uri uri = Serializer.GetUri(element, this.Provider, this.CurrentContainer, this.AbsoluteServiceUri);
this.writer.WriteStartElement(XmlConstants.UriElementName, XmlConstants.DataWebNamespace);
this.writer.WriteValue(uri.AbsoluteUri);
this.writer.WriteEndElement();
}
///
/// Write out the uri for the given elements
///
/// elements whose uri need to be writtne out
/// the current state of the enumerator.
protected override void WriteLinkCollection(IEnumerator elements, bool hasMoved)
{
this.writer.WriteStartElement(XmlConstants.LinkCollectionElementName, XmlConstants.DataWebNamespace);
// write count?
if (this.RequestDescription.CountOption == RequestQueryCountOption.Inline)
{
this.WriteRowCount();
}
object lastObject = null;
IExpandedResult lastExpandedSkipToken = null;
while (hasMoved)
{
object element = elements.Current;
IExpandedResult skipToken = null;
if (element != null)
{
IExpandedResult expanded = element as IExpandedResult;
if (expanded != null)
{
element = GetExpandedElement(expanded);
skipToken = this.GetSkipToken(expanded);
}
}
this.WriteLink(element);
hasMoved = elements.MoveNext();
lastObject = element;
lastExpandedSkipToken = skipToken;
}
if (this.NeedNextPageLink(elements))
{
this.WriteNextPageLink(lastObject, lastExpandedSkipToken, this.RequestDescription.ResultUri);
}
this.writer.WriteEndElement();
}
///
/// Writes the next page link to the current xml writer corresponding to the feed
///
/// Object that will contain the keys for skip token
/// The value of the $skiptoken property of the object being written
/// Absolute URI for the result
private void WriteNextPageLink(object lastElement, IExpandedResult expandedResult, Uri absoluteUri)
{
this.writer.WriteStartElement(XmlConstants.NextElementName, XmlConstants.DataWebNamespace);
this.writer.WriteValue(this.GetNextLinkUri(lastElement, expandedResult, absoluteUri));
this.writer.WriteEndElement();
}
/// Writes all the properties of the specified resource or complex object.
/// Resource or complex object with properties to write out.
/// Resource type describing the element type.
private void WriteObjectProperties(object element, ResourceType resourceType)
{
Debug.Assert(element != null, "element != null");
Debug.Assert(resourceType != null, "resourceType != null");
foreach (ResourceProperty property in resourceType.Properties)
{
string propertyName = property.Name;
object propertyValue = WebUtil.GetPropertyValue(this.Provider, element, resourceType, property, null);
bool needPop = this.PushSegmentForProperty(property);
if (property.TypeKind == ResourceTypeKind.ComplexType)
{
this.WriteComplexObjectValue(propertyValue, propertyName, property.ResourceType);
}
else
{
Debug.Assert(property.TypeKind == ResourceTypeKind.Primitive, "property.TypeKind == ResourceTypeKind.Primitive");
this.WritePrimitiveValue(propertyValue, property.Name, property.ResourceType);
}
this.PopSegmentName(needPop);
}
if (resourceType.IsOpenType)
{
IEnumerable> properties = this.Provider.GetOpenPropertyValues(element);
foreach (KeyValuePair property in properties)
{
string propertyName = property.Key;
object value = property.Value;
if (value == null || value == DBNull.Value)
{
continue;
}
ResourceType propertyResourceType = WebUtil.GetResourceType(this.Provider, value);
if (propertyResourceType == null)
{
continue;
}
if (propertyResourceType.ResourceTypeKind == ResourceTypeKind.Primitive)
{
this.WritePrimitiveValue(value, propertyName, propertyResourceType);
}
else
{
if (propertyResourceType.ResourceTypeKind == ResourceTypeKind.ComplexType)
{
Debug.Assert(propertyResourceType.InstanceType == value.GetType(), "propertyResourceType.Type == valueType");
this.WriteComplexObjectValue(value, propertyName, propertyResourceType);
}
else
{
Debug.Assert(propertyResourceType.ResourceTypeKind == ResourceTypeKind.EntityType, "EntityType expected.");
// Open navigation properties are not supported on OpenTypes
throw DataServiceException.CreateBadRequestError(Strings.OpenNavigationPropertiesNotSupportedOnOpenTypes(propertyName));
}
}
}
}
}
/// Writes a property with a primitive value.
/// Value.
/// Property name.
/// Type for element.
private void WritePrimitiveValue(object element, string propertyName, ResourceType type)
{
Debug.Assert(propertyName != null, "propertyName != null");
Debug.Assert(type != null, "type != null");
if (element == null)
{
WriteNullValue(this.writer, propertyName, type.FullName);
return;
}
string propertyText = PrimitiveToString(element);
WriteTextValue(this.writer, propertyName, type.FullName, propertyText);
}
/// Writes the value of a complex object.
/// Element to write.
/// Property name.
/// Type for element.
private void WriteComplexObjectValue(object element, string propertyName, ResourceType expectedType)
{
Debug.Assert(!String.IsNullOrEmpty(propertyName), "!String.IsNullOrEmpty(propertyName)");
Debug.Assert(expectedType != null, "expectedType != null");
Debug.Assert(expectedType.ResourceTypeKind == ResourceTypeKind.ComplexType, "Must be complex type");
if (element == null)
{
WriteNullValue(this.writer, propertyName, expectedType.FullName);
return;
}
// Non-value complex types may form a cycle.
// PERF: we can keep a single element around and save the HashSet initialization
// until we find a second complex type - this saves the allocation on trees
// with shallow (single-level) complex types.
this.RecurseEnter();
Debug.Assert(!expectedType.InstanceType.IsValueType, "!expectedType.Type.IsValueType -- checked in the resource type constructor.");
if (this.AddToComplexTypeCollection(element))
{
ResourceType resourceType = WebUtil.GetNonPrimitiveResourceType(this.Provider, element);
WriteStartElementWithType(this.writer, propertyName, resourceType.FullName);
this.WriteObjectProperties(element, resourceType);
this.writer.WriteEndElement();
this.RemoveFromComplexTypeCollection(element);
}
else
{
throw new InvalidOperationException(Strings.Serializer_LoopsNotAllowedInComplexTypes(propertyName));
}
this.RecurseLeave();
}
/// Writes the value with the specified name.
/// Element to write out.
/// Property name for element.
/// Type of resource to write.
private void WriteValueWithName(object element, string propertyName, ResourceType resourceType)
{
Debug.Assert(propertyName != null, "propertyName != null");
Debug.Assert(resourceType != null, "resourceType != null");
if (resourceType.ResourceTypeKind == ResourceTypeKind.Primitive)
{
this.WritePrimitiveValue(element, propertyName, resourceType);
}
else
{
Debug.Assert(
resourceType.ResourceTypeKind == ResourceTypeKind.ComplexType,
"resourceType.ResourceTypeKind == ResourceTypeKind.ComplexType -- POX doesn't support " + resourceType.ResourceTypeKind);
this.WriteComplexObjectValue(element, propertyName, resourceType);
}
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- TypedReference.cs
- ObjectNavigationPropertyMapping.cs
- PackageRelationship.cs
- TableLayoutCellPaintEventArgs.cs
- ActivationArguments.cs
- NumberAction.cs
- MetadataItem_Static.cs
- GAC.cs
- LocationUpdates.cs
- Int16Storage.cs
- RelationshipFixer.cs
- ExpressionLexer.cs
- ConfigPathUtility.cs
- SignatureToken.cs
- SetterBase.cs
- QilFactory.cs
- MenuItem.cs
- SortFieldComparer.cs
- ConditionValidator.cs
- SelectionProviderWrapper.cs
- ApplicationId.cs
- Transform3D.cs
- XmlNavigatorStack.cs
- EditorAttribute.cs
- ListChangedEventArgs.cs
- SiteOfOriginContainer.cs
- BuildResultCache.cs
- TraceContextEventArgs.cs
- StaticFileHandler.cs
- XMLSyntaxException.cs
- DataTable.cs
- WizardPanelChangingEventArgs.cs
- HtmlTableRow.cs
- DnsPermission.cs
- ServiceBehaviorElement.cs
- ConfigDefinitionUpdates.cs
- XmlSerializer.cs
- DBDataPermissionAttribute.cs
- Label.cs
- FileDialog.cs
- CodeAccessPermission.cs
- QilPatternVisitor.cs
- _LazyAsyncResult.cs
- EdmItemCollection.cs
- TripleDES.cs
- GridViewCommandEventArgs.cs
- AsmxEndpointPickerExtension.cs
- CFStream.cs
- RayHitTestParameters.cs
- SHA256CryptoServiceProvider.cs
- TableDetailsCollection.cs
- HealthMonitoringSectionHelper.cs
- CommonDialog.cs
- SetIterators.cs
- filewebrequest.cs
- InkCanvasAutomationPeer.cs
- LocatorPartList.cs
- CodeIndexerExpression.cs
- QueryTreeBuilder.cs
- DBSqlParserTableCollection.cs
- DataKey.cs
- URL.cs
- wgx_commands.cs
- PartitionResolver.cs
- GridItem.cs
- PropertyEntry.cs
- MetadataUtilsSmi.cs
- Camera.cs
- ButtonBaseAutomationPeer.cs
- CheckBoxAutomationPeer.cs
- RowType.cs
- Token.cs
- IxmlLineInfo.cs
- TextTreeUndo.cs
- RolePrincipal.cs
- ConfigurationPropertyAttribute.cs
- COM2Properties.cs
- TypeValidationEventArgs.cs
- CompositeKey.cs
- IIS7WorkerRequest.cs
- ProfilePropertySettings.cs
- ScrollPattern.cs
- ActivationServices.cs
- DataFieldConverter.cs
- HttpHandlersSection.cs
- DateTimeFormatInfo.cs
- XmlProcessingInstruction.cs
- DataSetUtil.cs
- TextUtf8RawTextWriter.cs
- DropShadowEffect.cs
- MemberRelationshipService.cs
- ArgIterator.cs
- UnsafeNativeMethods.cs
- EpmSourceTree.cs
- SecureStringHasher.cs
- TransformConverter.cs
- SqlDataReader.cs
- FixUp.cs
- CaseInsensitiveHashCodeProvider.cs
- ArraySubsetEnumerator.cs