To briefly summarize the breaking changes, most of them fall into one of four categories:

Improved Performance

We will get better writer performance across the board.

Introducing Dependency Injection

This feature will substantially increase extensibility, like allowing customers to replace entire components such as the UriPathParser with their own implementation. Introducing DI make it much easier to use the same reader/writer settings across the board.

Removed Legacy Code

There was a lot of vestigial code left around from the OData v1-3 days that we’ve removed.

Improved API Design

Most of our API improvements fall into the category of namespace simplifications or updating verbiage. The single most impactful change that we made was deciding to merge entity type and complex type in ODataLib. We did this because complex type and entity type are becoming more and more similar in the protocol, but we continue to pay overhead to make things work for both of them.

Changes in ODataLib 7.0 Release

New Features

[Issue #245] Support duplicate non-OData query options.

[Issue #248] Support untyped JSON.

  • This feature will allow customers to extend their OData payloads with arbitrary JSON. In the extreme, it’s theoretically possible for the whole response to be untyped.

[Issue #271] Support writing relative URIs in OData batch operations.

  • Add an enum type BatchPayloadUriOption to support three URI formats in batch payload.

[Issue #366] Support collection of mixed primitive types and Edm.Untyped.

[Issue #501] Integrate dependency injection (DI).

  • We introduced an abstraction layer consisting of two interfaces IContainerBuilder and IContainerProvider so that ODataLib is decoupled from any concrete implementation of DI framework. Now we support the following services to be replaced by users:

    • JSON reader via IJsonReaderFactory
    • JSON writer via IJsonWriterFactory
    • ODataMediaTypeResolver
    • ODataPayloadValueConverter
    • ODataUriResolver
    • UriPathParser
  • We also support prototype services. For each prototype service, you can specify a globally singleton prototype instance. Then for each request, a cloned instance will be created from that prototype which can isolate the modification within the request boundary. Currently we support three prototype services:

    • ODataMessageReaderSettings
    • ODataMessageWriterSettings
    • ODataSimplifiedOptions

[Issue #502] Support URI path syntax customization.

  • Expose UriPathParser.ParsePathIntoSegments to support customizing how to separate a Uri into segments
  • Provide ParseDynamicPathSegmentFunc for customizing how to parse a dynamic path segment.

[Issue #613] Support type facets when referencing TypeDefinition types.

[Issue #622] Support navigation property on complex types.

  • EdmLib supports adding navigation property on complex type in model.
  • ODataUriParser support parsing related Uri path or query expressions.
  • ODataLib support reading and writing navigation properties on complex type.

[Issue #629] Support multi-NavigationPropertyBindings for a single navigation property by using different paths

  • Navigation property used in multi bindings with different path is supported for navigation under containment and complex.

[Issue #631] Support fluent writer API.

  • In previous version, paired WriteStart and WriteEnd calls are used in writing payloads. This syntax is error-prone, and soon gets unmanageable with complex and deeply nested payloads. In this new release, you can instead write payloads using the neat fluent syntax.

[Issue #635] Support collection of nullable values for dynamic properties.

[Issue #637] Support system query options without $ prefix.

  • Expose ODataUriParser.EnableNoDollarQueryOptions flag to enable user to support ‘$’ system query prefix optional.

Add ODataSimplifiedOptions class for simplified reader, writer, URL parsing options.

Support duplicate custom instance annotations.

Fixed Bugs

[Issue #104] Function imports with parameters are included in service document.

[Issue #498] Typos in namespace/class names.

[Issue #508] YYYY-MM-DD in URI should be parsed into Date, not DataTimeOffset.

[Issue #556] URI template parser doesn’t work correctly if key is of an enum type.

[Issue #573] CollectionCount is not publicly accessible.

[Issue #592] ODataUriParser.ParsePath() doesn’t work correctly if EntitySetPath is not specified in model.

[Issue #628] Dynamic complex (collection) property is annotated with association and navigation links.

[Issue #638] Null value at the first position in a complex collection cannot be read.

[Issue #658] ODataValueUtils.ToODataValue doesn’t work with System.Enum objects.

Improvements

Legacy Code Clean-up

[Issue #385] Remove junk code to improve stability and reduce assembly size.

  • Deprecated build constants
  • Code in ODataLib that has duplication in EdmLib
  • Platform-dependent code (e.g., redefinition of TypeCode and BindingFlags, Silverlight code, etc.)
  • Deprecated classes like EntitySetNode

[Issue #500] Remove deprecated NuGet profiles

  • Removed support for:
    • Desktop and Profile328 for .NET 4.0
    • Profile259 for .NET 4.5
    • dnxcore50 and dnx451 for ASP.NET 5.0 (deprecated)
  • What we have now:
    • Profile111 for .NET 4.5 which is compatible with most .NET 4.5+ applications, UWP, Xamarin/Mono, etc.
    • .NET 3.5 for Office (will not be publicly available)

[Issue #510] Remove Atom support

[Issue #511] Clean property and method in ODataMessageReaderSettings and ODataMessageWriterSettings

  • Remove API to enable default, service and client settings
  • Move ODataSimplified and UseKeyAsSegment to ODataSimplifiedOptions
  • Rename DisableXXX to EnableXXX
  • Remove base class of reader and writer settings

[Issue #548] Rename “value term” and “value annotation” in EdmLib.

  • “Value term” and “value annotation” are concepts of ODataV3, In ODataV4 we remove/rename obsolete interfaces and merge some interfaces with their base interfaces so as to make APIs clearer and more compact.

[Issue #565] Update CoreVocabularies.xml to the new version and related APIs.

[Issue #564] Remove Edm.ConcurrencyMode attribute from Property.

[Issue #606] Remove V3 vocabulary expressions

  • Interfaces removed: IEdmEnumMemberReferenceExpression, IEdmEnumMemberReferenceExpression, IEdmEntitySetReferenceExpression, IEdmPropertyReferenceExpression, IEdmParameterReferenceExpression and IEdmOperationReferenceExpression
  • For the previous IEdmEntitySetReferenceExpression, please use IEdmPathExpression where users need to provide a path (a list of strings) to a navigation property with which we can resolve the target entity set from the navigation source.
  • For the previous IEdmOperationReferenceExpression, please use IEdmFunction because the Edm.Apply only accepts an EDM function in OData V4. This also simplifies the structure of Edm.Apply expression.

[Issue #618] Remove deprecated validation rules

  • ComplexTypeInvalidAbstractComplexType
  • ComplexTypeInvalidPolymorphicComplexType
  • ComplexTypeMustContainProperties
  • OnlyEntityTypesCanBeOpen

Public API Simplification

[Issue #504] Unify entity and complex (collection) type serialization/deserialization API.

  • Merge the reading/writing behavior for complex and entity, collection of complex and collection of entity.
    • Change ODataEntry to ODataResource and remove ODataComplexValue to support complex and entity.
    • Change ODataFeed to ODataResourceSet to support feed and complex collection.
    • Change ODataNavigationLink to ODataNestedResourceInfo to support navigation property and complex property or complex collection property.
    • Change reader/writer APIs to support IEdmStructuredType.
  • We don’t merge entity type/complex type in EdmLib since they are OData concepts.

[Issue #491] Simplified namespaces.

[Issue #517] Centralized reader/writer validation. [Breaking Changes]

  • Add an enum ValidationKinds to represent all validation kinds in reader and writer.
  • Add Validations property in ODataMessageWriterSettings/ODataMessageReaderSettings to control validations.
  • Remove some APIs.

[Issue #571] Rename ODataUrlConvention to ODataUrlKeyDelimiter

  • Rename ODataUrlConvention to ODataUrlKeyDelimiter.
  • Use ODataUrlKeyDelimiter.Slash instead of ODataUrlConvention.Simplified or ODataUrlConvention.KeyAsSegment
  • Use ODataUrlKeyDelimiter.Parentheses instead of ODataUrlConvention.Default

[Issue #614] Improve API design around ODataAnnotatable

  • Merge SerializationTypeNameAnnotation into ODataTypeAnnotation
  • Refactor ODataTypeAnnotation to contain only the type name
  • Remove unnecessary inheritance from ODataAnnotatable in URI parser and simplify the API of ODataAnnotatble
  • GetAnnotation<T>() and SetAnnotation<T>() will no longer be available because ODataAnnotatable should only be responsible for managing instance annotations.

Public API Enhancement

[Issue #484] Preference header extensibility

  • Public class HttpHeaderValueElement, which represents http header value element
  • Remove sealed from public class ODataPreferenceHeader

[Issue #544] Change Enum member value type from IEdmPrimitiveValue to a more specific type.

  • Add interface IEdmEnumMemberValue and class EdmEnumMemberValue to represent enum member value specifically. AddMember() under EnumType now accepts IEdmEnumMemberValue instead of IEdmPrimitiveValue as member value.

[Issue #621] Make reader able to read contained entity/entityset without context URL.

[Issue #640] More sensible type, namely IEnumerable, for ODataCollectionValue.Items.

[Issue #643] Adjust query node kinds in Uri Parser in order to support navigation under complex. [Breaking Changes]

Improved standard-compliance by forbidding duplicate property names.

Writer throws more accurate and descriptive exceptions.

Other Improvements

[Issue #493] Replace ThrowOnUndeclaredProperty with the more accurate ThrowOnUndeclaredPropertyForNonOpenType.

[Issue #551] Change the type of EdmReference.Uri to System.Uri.

[Issue #558, [Issue #611] Improve writer performance. Up to 25% improvements compared to ODL 6.15 are achieved depending on scenario.

[Issue #632] Rename CsdlXXX to SchemaXXX, and EdmxXXX to CsdlXXX.

The original naming is confusing. According to the CSDL spec:

An XML document using these namespaces and having an edmx:Edmx root element will be called a CSDL document.

So, Edmx is only part of a valid CSDL document. In previous version, CsdlReader is actually unable to read a CSDL document. It’s only able to read the Schema part of it. EdmxReader, on the other hand, is able to read a whole CSDL document. To clear up the concepts, the following renaming has been done:

  1. CsdlReader/Writer to SchemaReader/Writer;
  2. EdmxReader/Writer to CsdlReader/Writer;
  3. EdmxReaderSettings to CsdlReaderSettings;
  4. EdmxTarget to CsdlTarget.

Notes

This release delivers OData core libraries including ODataLib, EdmLib and Spatial. OData Client for .NET is not published in this release.