Пример #1
0
        private static string CreateDateTimeStringValue(object propertyValue, ODataWriterBehavior writerBehavior)
        {
            Debug.Assert(
                writerBehavior.FormatBehaviorKind == ODataBehaviorKind.WcfDataServicesClient,
                "CreateDateTimeStringValue should only be used in WCF DS client mode.");

            if (propertyValue == null)
            {
                propertyValue = DateTimeOffset.Now;
            }

            if (propertyValue is DateTime)
            {
                // DateTimeOffset takes care of DateTimes of Unspecified kind so we won't end up
                // with datetime without timezone info mapped to atom:updated or atom:published element.
                propertyValue = new DateTimeOffset((DateTime)propertyValue);
            }

            // For DateTimeOffset values we need to use the ATOM format when translating them
            // to strings since the value will be used in ATOM metadata.
            if (propertyValue is DateTimeOffset)
            {
                return(ODataAtomConvert.ToAtomString((DateTimeOffset)propertyValue));
            }

            return(EpmWriterUtils.GetPropertyValueAsText(propertyValue));
        }
Пример #2
0
        public void ApplyCommonSettingsUsesODataServerBehavior()
        {
            var testSubject = new ODataMessageWriterSettings();

            testSubject.EnableDefaultBehavior();
            MessageWriterBuilder.ApplyCommonSettings(testSubject, new Uri("http://www.example.com"), VersionUtil.Version4Dot0, this.dataServiceSimulator, this.responseMessageSimulator);
            testSubject.WriterBehavior.ShouldHave().AllProperties().EqualTo(ODataWriterBehavior.CreateODataServerBehavior());
        }
Пример #3
0
 private static string CreateDateTimeStringValue(object propertyValue, ODataWriterBehavior writerBehavior)
 {
     if (propertyValue == null)
     {
         propertyValue = DateTimeOffset.Now;
     }
     if (propertyValue is DateTime)
     {
         propertyValue = new DateTimeOffset((DateTime)propertyValue);
     }
     if (propertyValue is DateTimeOffset)
     {
         return(ODataAtomConvert.ToAtomString((DateTimeOffset)propertyValue));
     }
     return(EpmWriterUtils.GetPropertyValueAsText(propertyValue));
 }
        internal static AtomEntryMetadata MergeCustomAndEpmEntryMetadata(AtomEntryMetadata customEntryMetadata, AtomEntryMetadata epmEntryMetadata, ODataWriterBehavior writerBehavior)
        {
            AtomEntryMetadata metadata;

            if ((customEntryMetadata != null) && (writerBehavior.FormatBehaviorKind == ODataBehaviorKind.WcfDataServicesClient))
            {
                if (customEntryMetadata.Updated.HasValue)
                {
                    customEntryMetadata.UpdatedString = ODataAtomConvert.ToAtomString(customEntryMetadata.Updated.Value);
                }
                if (customEntryMetadata.Published.HasValue)
                {
                    customEntryMetadata.PublishedString = ODataAtomConvert.ToAtomString(customEntryMetadata.Published.Value);
                }
            }
            if (TryMergeIfNull <AtomEntryMetadata>(customEntryMetadata, epmEntryMetadata, out metadata))
            {
                return(metadata);
            }
            epmEntryMetadata.Title   = MergeAtomTextValue(customEntryMetadata.Title, epmEntryMetadata.Title, "Title");
            epmEntryMetadata.Summary = MergeAtomTextValue(customEntryMetadata.Summary, epmEntryMetadata.Summary, "Summary");
            epmEntryMetadata.Rights  = MergeAtomTextValue(customEntryMetadata.Rights, epmEntryMetadata.Rights, "Rights");
            if (writerBehavior.FormatBehaviorKind == ODataBehaviorKind.WcfDataServicesClient)
            {
                epmEntryMetadata.PublishedString = MergeTextValue(customEntryMetadata.PublishedString, epmEntryMetadata.PublishedString, "PublishedString");
                epmEntryMetadata.UpdatedString   = MergeTextValue(customEntryMetadata.UpdatedString, epmEntryMetadata.UpdatedString, "UpdatedString");
            }
            else
            {
                epmEntryMetadata.Published = MergeDateTimeValue(customEntryMetadata.Published, epmEntryMetadata.Published, "Published");
                epmEntryMetadata.Updated   = MergeDateTimeValue(customEntryMetadata.Updated, epmEntryMetadata.Updated, "Updated");
            }
            epmEntryMetadata.Authors      = MergeSyndicationMapping <AtomPersonMetadata>(customEntryMetadata.Authors, epmEntryMetadata.Authors);
            epmEntryMetadata.Contributors = MergeSyndicationMapping <AtomPersonMetadata>(customEntryMetadata.Contributors, epmEntryMetadata.Contributors);
            epmEntryMetadata.Categories   = MergeSyndicationMapping <AtomCategoryMetadata>(customEntryMetadata.Categories, epmEntryMetadata.Categories);
            epmEntryMetadata.Links        = MergeSyndicationMapping <AtomLinkMetadata>(customEntryMetadata.Links, epmEntryMetadata.Links);
            epmEntryMetadata.Source       = customEntryMetadata.Source;
            return(epmEntryMetadata);
        }
Пример #5
0
        private static DateTimeOffset CreateDateTimeValue(object propertyValue, SyndicationItemProperty targetProperty, ODataWriterBehavior writerBehavior)
        {
            Debug.Assert(
                writerBehavior.FormatBehaviorKind != ODataBehaviorKind.WcfDataServicesClient,
                "CreateDateTimeValue should not be used in WCF DS client mode.");

            if (propertyValue == null)
            {
                return(DateTimeOffset.Now);
            }

            if (propertyValue is DateTimeOffset)
            {
                return((DateTimeOffset)propertyValue);
            }

            if (propertyValue is DateTime)
            {
                // DateTimeOffset takes care of DateTimes of Unspecified kind so we won't end up
                // with datetime without timezone info mapped to atom:updated or atom:published element.
                return(new DateTimeOffset((DateTime)propertyValue));
            }

            string stringValue = propertyValue as string;

            if (stringValue != null)
            {
                DateTimeOffset date;
                if (!DateTimeOffset.TryParse(stringValue, out date))
                {
                    DateTime result;
                    if (!DateTime.TryParse(stringValue, out result))
                    {
                        throw new ODataException(o.Strings.EpmSyndicationWriter_DateTimePropertyCanNotBeConverted(targetProperty.ToString()));
                    }

                    return(new DateTimeOffset(result));
                }

                return(date);
            }

            try
            {
                return(new DateTimeOffset(Convert.ToDateTime(propertyValue, CultureInfo.InvariantCulture)));
            }
            catch (Exception e)
            {
                if (!ExceptionUtils.IsCatchableExceptionType(e))
                {
                    throw;
                }

                throw new ODataException(o.Strings.EpmSyndicationWriter_DateTimePropertyCanNotBeConverted(targetProperty.ToString()));
            }
        }
Пример #6
0
 /// <summary>
 /// Constructor to create a new entry scope.
 /// </summary>
 /// <param name="entry">The entry for the new scope.</param>
 /// <param name="skipWriting">true if the content of the scope to create should not be written.</param>
 /// <param name="writingResponse">true if we are writing a response, false if it's a request.</param>
 /// <param name="writerBehavior">The <see cref="ODataWriterBehavior"/> instance controlling the behavior of the writer.</param>
 internal AtomEntryScope(ODataEntry entry, bool skipWriting, bool writingResponse, ODataWriterBehavior writerBehavior)
     : base(entry, skipWriting, writingResponse, writerBehavior)
 {
     DebugUtils.CheckNoExternalCallers();
 }
Пример #7
0
 /// <summary>
 /// Constructor to create a new entry scope.
 /// </summary>
 /// <param name="entry">The entry for the new scope.</param>
 /// <param name="serializationInfo">The serialization info for the current entry.</param>
 /// <param name="navigationSource">The navigation source we are going to write entities for.</param>
 /// <param name="entityType">The entity type for the entries in the feed to be written (or null if the entity set base type should be used).</param>
 /// <param name="skipWriting">true if the content of the scope to create should not be written.</param>
 /// <param name="writingResponse">true if we are writing a response, false if it's a request.</param>
 /// <param name="writerBehavior">The <see cref="ODataWriterBehavior"/> instance controlling the behavior of the writer.</param>
 /// <param name="selectedProperties">The selected properties of this scope.</param>
 /// <param name="odataUri">The ODataUri info of this scope.</param>
 internal AtomEntryScope(ODataEntry entry, ODataFeedAndEntrySerializationInfo serializationInfo, IEdmNavigationSource navigationSource, IEdmEntityType entityType, bool skipWriting, bool writingResponse, ODataWriterBehavior writerBehavior, SelectedPropertiesNode selectedProperties, ODataUri odataUri)
     : base(entry, serializationInfo, navigationSource, entityType, skipWriting, writingResponse, writerBehavior, selectedProperties, odataUri)
 {
 }
 /// <summary>
 /// Constructor to create a new delta link scope.
 /// </summary>
 /// <param name="state">The writer state of this scope.</param>
 /// <param name="link">The link for the new scope.</param>
 /// <param name="serializationInfo">The serialization info for the current entry.</param>
 /// <param name="navigationSource">The navigation source we are going to write entities for.</param>
 /// <param name="entityType">The entity type for the entries in the feed to be written (or null if the entity set base type should be used).</param>
 /// <param name="writerBehavior">The <see cref="ODataWriterBehavior"/> instance controlling the behavior of the writer.</param>
 /// <param name="selectedProperties">The selected properties of this scope.</param>
 /// <param name="odataUri">The ODataUri info of this scope.</param>
 internal JsonLightDeltaLinkScope(WriterState state, ODataItem link, ODataDeltaSerializationInfo serializationInfo, IEdmNavigationSource navigationSource, IEdmEntityType entityType, ODataWriterBehavior writerBehavior, SelectedPropertiesNode selectedProperties, ODataUri odataUri)
     : base(state, link, serializationInfo, navigationSource, entityType, writerBehavior, selectedProperties, odataUri)
 {
 }
            /// <summary>
            /// Constructor to create a new delta link scope.
            /// </summary>
            /// <param name="state">The writer state of this scope.</param>
            /// <param name="link">The link for the new scope.</param>
            /// <param name="serializationInfo">The serialization info for the current entry.</param>
            /// <param name="navigationSource">The navigation source we are going to write entities for.</param>
            /// <param name="entityType">The entity type for the entries in the feed to be written (or null if the entity set base type should be used).</param>
            /// <param name="writerBehavior">The <see cref="ODataWriterBehavior"/> instance controlling the behavior of the writer.</param>
            /// <param name="selectedProperties">The selected properties of this scope.</param>
            /// <param name="odataUri">The ODataUri info of this scope.</param>
            protected DeltaLinkScope(WriterState state, ODataItem link, ODataDeltaSerializationInfo serializationInfo, IEdmNavigationSource navigationSource, IEdmEntityType entityType, ODataWriterBehavior writerBehavior, SelectedPropertiesNode selectedProperties, ODataUri odataUri)
                : base(state, link, navigationSource, entityType, selectedProperties, odataUri)
            {
                Debug.Assert(link != null, "link != null");
                Debug.Assert(
                    state == WriterState.DeltaLink && link is ODataDeltaLink ||
                    state == WriterState.DeltaDeletedLink && link is ODataDeltaDeletedLink,
                    "link must be either DeltaLink or DeltaDeletedLink.");
                Debug.Assert(writerBehavior != null, "writerBehavior != null");

                this.serializationInfo = DeltaConverter.ToFeedAndEntrySerializationInfo(serializationInfo);
            }
            /// <summary>
            /// Constructor to create a new entry scope.
            /// </summary>
            /// <param name="state">The writer state of this scope.</param>
            /// <param name="entry">The entry for the new scope.</param>
            /// <param name="serializationInfo">The serialization info for the current entry.</param>
            /// <param name="navigationSource">The navigation source we are going to write entities for.</param>
            /// <param name="entityType">The entity type for the entries in the feed to be written (or null if the entity set base type should be used).</param>
            /// <param name="writerBehavior">The <see cref="ODataWriterBehavior"/> instance controlling the behavior of the writer.</param>
            /// <param name="selectedProperties">The selected properties of this scope.</param>
            /// <param name="odataUri">The ODataUri info of this scope.</param>
            protected DeltaEntryScope(WriterState state, ODataItem entry, ODataFeedAndEntrySerializationInfo serializationInfo, IEdmNavigationSource navigationSource, IEdmEntityType entityType, ODataWriterBehavior writerBehavior, SelectedPropertiesNode selectedProperties, ODataUri odataUri)
                : base(state, entry, navigationSource, entityType, selectedProperties, odataUri)
            {
                Debug.Assert(entry != null, "entry != null");
                Debug.Assert(
                    state == WriterState.DeltaEntry && entry is ODataEntry ||
                    state == WriterState.DeltaDeletedEntry && entry is ODataDeltaDeletedEntry,
                    "entry must be either DeltaEntry or DeltaDeletedEntry.");
                Debug.Assert(writerBehavior != null, "writerBehavior != null");

                this.duplicatePropertyNamesChecker = new DuplicatePropertyNamesChecker(writerBehavior.AllowDuplicatePropertyNames, /*writingResponse*/ true);
                this.serializationInfo = serializationInfo;
            }
 /// <summary>
 /// Constructor to create a new entry scope.
 /// </summary>
 /// <param name="entry">The entry for the new scope.</param>
 /// <param name="serializationInfo">The serialization info for the current entry.</param>
 /// <param name="navigationSource">The navigation source we are going to write entities for.</param>
 /// <param name="entityType">The entity type for the entries in the feed to be written (or null if the entity set base type should be used).</param>
 /// <param name="skipWriting">true if the content of the scope to create should not be written.</param>
 /// <param name="writingResponse">true if we are writing a response, false if it's a request.</param>
 /// <param name="writerBehavior">The <see cref="ODataWriterBehavior"/> instance controlling the behavior of the writer.</param>
 /// <param name="selectedProperties">The selected properties of this scope.</param>
 /// <param name="odataUri">The ODataUri info of this scope.</param>
 /// <param name="enableValidation">Enable validation or not.</param>
 internal JsonLightEntryScope(ODataEntry entry, ODataFeedAndEntrySerializationInfo serializationInfo, IEdmNavigationSource navigationSource, IEdmEntityType entityType, bool skipWriting, bool writingResponse, ODataWriterBehavior writerBehavior, SelectedPropertiesNode selectedProperties, ODataUri odataUri, bool enableValidation)
     : base(entry, serializationInfo, navigationSource, entityType, skipWriting, writingResponse, writerBehavior, selectedProperties, odataUri, enableValidation)
 {
 }
Пример #12
0
 /// <summary>
 /// Constructor to create a new entry scope.
 /// </summary>
 /// <param name="entry">The entry for the new scope.</param>
 /// <param name="serializationInfo">The serialization info for the current entry.</param>
 /// <param name="entitySet">The entity set we are going to write entities for.</param>
 /// <param name="entityType">The entity type for the entries in the feed to be written (or null if the entity set base type should be used).</param>
 /// <param name="skipWriting">true if the content of the scope to create should not be written.</param>
 /// <param name="writingResponse">true if we are writing a response, false if it's a request.</param>
 /// <param name="writerBehavior">The <see cref="ODataWriterBehavior"/> instance controlling the behavior of the writer.</param>
 /// <param name="selectedProperties">The selected properties of this scope.</param>
 internal AtomEntryScope(ODataEntry entry, ODataFeedAndEntrySerializationInfo serializationInfo, IEdmEntitySet entitySet, IEdmEntityType entityType, bool skipWriting, bool writingResponse, ODataWriterBehavior writerBehavior, SelectedPropertiesNode selectedProperties)
     : base(entry, serializationInfo, entitySet, entityType, skipWriting, writingResponse, writerBehavior, selectedProperties)
 {
     DebugUtils.CheckNoExternalCallers();
 }
 /// <summary>
 /// Constructor to create a new entry scope.
 /// </summary>
 /// <param name="state">The writer state of the scope to create.</param>
 /// <param name="entry">The entry for the new scope.</param>
 /// <param name="serializationInfo">The serialization info for the current entry.</param>
 /// <param name="navigationSource">The navigation source we are going to write entities for.</param>
 /// <param name="entityType">The entity type for the entries in the feed to be written (or null if the entity set base type should be used).</param>
 /// <param name="writerBehavior">The <see cref="ODataWriterBehavior"/> instance controlling the behavior of the writer.</param>
 /// <param name="selectedProperties">The selected properties of this scope.</param>
 /// <param name="odataUri">The ODataUri info of this scope.</param>
 public JsonLightDeltaEntryScope(WriterState state, ODataItem entry, ODataFeedAndEntrySerializationInfo serializationInfo, IEdmNavigationSource navigationSource, IEdmEntityType entityType, ODataWriterBehavior writerBehavior, SelectedPropertiesNode selectedProperties, ODataUri odataUri)
     : base(state, entry, serializationInfo, navigationSource, entityType, writerBehavior, selectedProperties, odataUri)
 {
 }
Пример #14
0
 internal AtomEntryScope(ODataEntry entry, bool skipWriting, bool writingResponse, ODataWriterBehavior writerBehavior) : base(entry, skipWriting, writingResponse, writerBehavior)
 {
 }
Пример #15
0
        /// <summary>
        /// Merges custom and EPM ATOM metadata.
        /// </summary>
        /// <param name="customEntryMetadata">The custom ATOM metadata, or null if there were no custom ATOM metadata.</param>
        /// <param name="epmEntryMetadata">The EPM ATOM metadata, or null if there are no EPM mappings to syndication targets.</param>
        /// <param name="writerBehavior">The <see cref="ODataWriterBehavior"/> instance configuring the writer.</param>
        /// <returns>The merged ATOM metadata to write to the output.</returns>
        /// <remarks>The merge means that if one of the sides has null, the other is used, otherwise if both are non-null
        /// we verify that the values are the same, otherwise we throw.</remarks>
        internal static AtomEntryMetadata MergeCustomAndEpmEntryMetadata(AtomEntryMetadata customEntryMetadata, AtomEntryMetadata epmEntryMetadata, ODataWriterBehavior writerBehavior)
        {
            DebugUtils.CheckNoExternalCallers();

            if (customEntryMetadata != null && writerBehavior.FormatBehaviorKind == ODataBehaviorKind.WcfDataServicesClient)
            {
                // ODataLib supports specifying ATOM metadata for entries even in the WCF DS client mode;
                // WCF DS itself will never do this but ODataLib clients using this mode might. We have
                // to convert potential Published and Updated values to the internal string properties
                // used in WCF DS client mode.
                if (customEntryMetadata.Updated.HasValue)
                {
                    customEntryMetadata.UpdatedString = ODataAtomConvert.ToAtomString(customEntryMetadata.Updated.Value);
                }

                if (customEntryMetadata.Published.HasValue)
                {
                    customEntryMetadata.PublishedString = ODataAtomConvert.ToAtomString(customEntryMetadata.Published.Value);
                }
            }

            AtomEntryMetadata simpleMergeResult;

            if (TryMergeIfNull(customEntryMetadata, epmEntryMetadata, out simpleMergeResult))
            {
                return(simpleMergeResult);
            }

            // We will be modifying the EPM metadata adding the custom into it
            // The reason is that with EPM we can be sure that the enumerations are of type List (since they were created like that) and thus
            // we can safely add items into those without reallocating the collections.

            // Merge Title
            epmEntryMetadata.Title = MergeAtomTextValue(customEntryMetadata.Title, epmEntryMetadata.Title, "Title");

            // Merge Summary
            epmEntryMetadata.Summary = MergeAtomTextValue(customEntryMetadata.Summary, epmEntryMetadata.Summary, "Summary");

            // Merge Rights
            epmEntryMetadata.Rights = MergeAtomTextValue(customEntryMetadata.Rights, epmEntryMetadata.Rights, "Rights");

            if (writerBehavior.FormatBehaviorKind == ODataBehaviorKind.WcfDataServicesClient)
            {
                // Merge PublishedString
                epmEntryMetadata.PublishedString = MergeTextValue(customEntryMetadata.PublishedString, epmEntryMetadata.PublishedString, "PublishedString");

                // Merge UpdatedString
                epmEntryMetadata.UpdatedString = MergeTextValue(customEntryMetadata.UpdatedString, epmEntryMetadata.UpdatedString, "UpdatedString");
            }
            else
            {
                // Merge Published
                epmEntryMetadata.Published = MergeDateTimeValue(customEntryMetadata.Published, epmEntryMetadata.Published, "Published");

                // Merge Updated
                epmEntryMetadata.Updated = MergeDateTimeValue(customEntryMetadata.Updated, epmEntryMetadata.Updated, "Updated");
            }

            // Merge authors
            epmEntryMetadata.Authors = MergeSyndicationMapping <AtomPersonMetadata>(customEntryMetadata.Authors, epmEntryMetadata.Authors);

            // Merge contributors
            epmEntryMetadata.Contributors = MergeSyndicationMapping <AtomPersonMetadata>(customEntryMetadata.Contributors, epmEntryMetadata.Contributors);

            // Merge Categories
            epmEntryMetadata.Categories = MergeSyndicationMapping <AtomCategoryMetadata>(customEntryMetadata.Categories, epmEntryMetadata.Categories);

            // Merge Links
            epmEntryMetadata.Links = MergeSyndicationMapping <AtomLinkMetadata>(customEntryMetadata.Links, epmEntryMetadata.Links);

            // Source
            // Copy the source element over from custom metadata since EPM doesn't use it yet.
            Debug.Assert(epmEntryMetadata.Source == null, "Once EPM actually writes to source element, implement the merge with custom metadata here.");
            epmEntryMetadata.Source = customEntryMetadata.Source;

            return(epmEntryMetadata);
        }
Пример #16
0
        private static DateTimeOffset CreateDateTimeValue(object propertyValue, SyndicationItemProperty targetProperty, ODataWriterBehavior writerBehavior)
        {
            DateTimeOffset offset;
            DateTime       time;

            if (propertyValue == null)
            {
                return(DateTimeOffset.Now);
            }
            if (propertyValue is DateTimeOffset)
            {
                return((DateTimeOffset)propertyValue);
            }
            if (propertyValue is DateTime)
            {
                return(new DateTimeOffset((DateTime)propertyValue));
            }
            string input = propertyValue as string;

            if (input == null)
            {
                DateTimeOffset offset2;
                try
                {
                    offset2 = new DateTimeOffset(Convert.ToDateTime(propertyValue, CultureInfo.InvariantCulture));
                }
                catch (Exception exception)
                {
                    if (!ExceptionUtils.IsCatchableExceptionType(exception))
                    {
                        throw;
                    }
                    throw new ODataException(Microsoft.Data.OData.Strings.EpmSyndicationWriter_DateTimePropertyCanNotBeConverted(targetProperty.ToString()));
                }
                return(offset2);
            }
            if (DateTimeOffset.TryParse(input, out offset))
            {
                return(offset);
            }
            if (!DateTime.TryParse(input, out time))
            {
                throw new ODataException(Microsoft.Data.OData.Strings.EpmSyndicationWriter_DateTimePropertyCanNotBeConverted(targetProperty.ToString()));
            }
            return(new DateTimeOffset(time));
        }