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)); }
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()); }
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); }
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())); } }
/// <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(); }
/// <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) { }
/// <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) { }
internal AtomEntryScope(ODataEntry entry, bool skipWriting, bool writingResponse, ODataWriterBehavior writerBehavior) : base(entry, skipWriting, writingResponse, writerBehavior) { }
/// <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); }
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)); }