diff --git a/src/Microsoft.OData.Core/ODataPreferenceHeader.cs b/src/Microsoft.OData.Core/ODataPreferenceHeader.cs
index 5e8bd02db9..42c05f007e 100644
--- a/src/Microsoft.OData.Core/ODataPreferenceHeader.cs
+++ b/src/Microsoft.OData.Core/ODataPreferenceHeader.cs
@@ -46,6 +46,21 @@ public sealed class ODataPreferenceHeader
///
private const string WaitPreferenceTokenName = "wait";
+ ///
+ /// The odata.continue-on-error preference token.
+ ///
+ private const string ODataContinueOnErrorPreferenceToken = "odata.continue-on-error";
+
+ ///
+ /// The odata.maxpagesize=# preference token.
+ ///
+ private const string ODataMaxPageSizePreferenceToken = "odata.maxpagesize";
+
+ ///
+ /// The odata.track-changes preference token.
+ ///
+ private const string ODataTrackChangesPreferenceToken = "odata.track-changes";
+
///
/// The Prefer header name.
///
@@ -61,6 +76,11 @@ public sealed class ODataPreferenceHeader
///
private static readonly KeyValuePair[] EmptyParameters = new KeyValuePair[0];
+ ///
+ /// The odata.continue-on-error preference.
+ ///
+ private static readonly HttpHeaderValueElement ContinueOnErrorPreference = new HttpHeaderValueElement(ODataContinueOnErrorPreferenceToken, null, EmptyParameters);
+
///
/// The return=minimal preference.
///
@@ -76,6 +96,11 @@ public sealed class ODataPreferenceHeader
///
private static readonly HttpHeaderValueElement RespondAsyncPreference = new HttpHeaderValueElement(RespondAsyncPreferenceToken, null, EmptyParameters);
+ ///
+ /// The odata.track-changes preference.
+ ///
+ private static readonly HttpHeaderValueElement TrackChangesPreference = new HttpHeaderValueElement(ODataTrackChangesPreferenceToken, null, EmptyParameters);
+
///
/// The message to set the preference header to and to get the preference header from.
///
@@ -288,6 +313,98 @@ private HttpHeaderValue Preferences
get { return this.preferences ?? (this.preferences = this.ParsePreferences()); }
}
+ ///
+ /// Property to get and set the "odata.continue-on-error" preference to the "Prefer" header on the underlying IODataRequestMessage or
+ /// the "Preference-Applied" header on the underlying IODataResponseMessage.
+ /// Setting true sets the "odata.continue-on-error" preference.
+ /// Setting false clears the "odata.continue-on-error" preference.
+ /// Returns true of the "odata.continue-on-error" preference is on the header. Otherwise returns false if the "odata.continue-on-error" is not on the header.
+ ///
+ public bool ContinueOnError
+ {
+ get
+ {
+ return this.Get(ODataContinueOnErrorPreferenceToken) != null;
+ }
+
+ set
+ {
+ if (value)
+ {
+ this.Set(ContinueOnErrorPreference);
+ }
+ else
+ {
+ this.Clear(ODataContinueOnErrorPreferenceToken);
+ }
+ }
+ }
+
+ ///
+ /// Property to get and set the "odata.maxpagesize" preference to the "Prefer" header on the underlying IODataRequestMessage or
+ /// the "Preference-Applied" header on the underlying IODataResponseMessage.
+ /// Setting N sets the "odata.maxpagesize=N" preference.
+ /// Setting null clears the "odata.maxpagesize" preference.
+ /// Returns N if the "odata.maxpagesize=N" preference is on the header.
+ /// Returning null indicates that "odata.maxpagesize" is not on the header.
+ ///
+ public int? MaxPageSize
+ {
+ get
+ {
+ var maxPageSizeHttpHeaderValueElement = this.Get(ODataMaxPageSizePreferenceToken);
+
+ // Should check maxPageSizeHttpHeaderValueElement.Value != null.
+ // Should do int.TryParse.
+ // If either of the above fail, should throw an ODataException for parsing, not a System.Exception (such as FormatException, etc.).
+ if (maxPageSizeHttpHeaderValueElement != null)
+ {
+ return int.Parse(maxPageSizeHttpHeaderValueElement.Value, CultureInfo.InvariantCulture);
+ }
+
+ return null;
+ }
+
+ set
+ {
+ if (value.HasValue)
+ {
+ this.Set(new HttpHeaderValueElement(ODataMaxPageSizePreferenceToken, string.Format(CultureInfo.InvariantCulture, "{0}", value.Value), EmptyParameters));
+ }
+ else
+ {
+ this.Clear(ODataMaxPageSizePreferenceToken);
+ }
+ }
+ }
+
+ ///
+ /// Property to get and set the "odata.track-changes" preference to the "Prefer" header on the underlying IODataRequestMessage or
+ /// the "Preference-Applied" header on the underlying IODataResponseMessage.
+ /// Setting true sets the "odata.track-changes" preference.
+ /// Setting false clears the "odata.track-changes" preference.
+ /// Returns true of the "odata.track-changes" preference is on the header. Otherwise returns false if the "odata.track-changes" is not on the header.
+ ///
+ public bool TrackChanges
+ {
+ get
+ {
+ return this.Get(ODataTrackChangesPreferenceToken) != null;
+ }
+
+ set
+ {
+ if (value)
+ {
+ this.Set(TrackChangesPreference);
+ }
+ else
+ {
+ this.Clear(ODataTrackChangesPreferenceToken);
+ }
+ }
+ }
+
///
/// Adds quotes around the given text value.
///
diff --git a/test/FunctionalTests/Tests/DataOData/Tests/OData.TDD.Tests/Common/ODataPreferenceHeaderTests.cs b/test/FunctionalTests/Tests/DataOData/Tests/OData.TDD.Tests/Common/ODataPreferenceHeaderTests.cs
index e1b726c129..995eb99838 100644
--- a/test/FunctionalTests/Tests/DataOData/Tests/OData.TDD.Tests/Common/ODataPreferenceHeaderTests.cs
+++ b/test/FunctionalTests/Tests/DataOData/Tests/OData.TDD.Tests/Common/ODataPreferenceHeaderTests.cs
@@ -30,6 +30,9 @@ public class ODataPreferenceHeaderTests
private const string RespondAyncPreference = "respond-async";
private const string RespondAsyncAndWaitPreference = "respond-async,wait=10";
private const string WaitPreference = "wait=10";
+ private const string MaxPageSizePreference = "odata.maxpagesize";
+ private const string TrackChangesPreference = "odata.track-changes";
+ private const string ContinueOnErrorPreference = "odata.continue-on-error";
[TestInitialize]
public void TestInit()
@@ -250,5 +253,64 @@ public void ReturnWaitOfBadIntergerFormatShouldThrow()
Action test = () => wait = this.preferHeader.Wait;
test.ShouldThrow().WithMessage("Input string was not in a correct format.");
}
+
+ [TestMethod]
+ public void SetContinueOnErrorToTrueShouldAppendHeader()
+ {
+ this.preferHeader.ContinueOnError = true;
+ this.preferHeader.ContinueOnError.Should().BeTrue();
+ this.requestMessage.GetHeader(PreferHeaderName).Should().Be(ContinueOnErrorPreference);
+ }
+
+ [TestMethod]
+ public void SetContinueOnErrorToFalseShouldClearHeader()
+ {
+ this.preferHeader.ContinueOnError = false;
+ this.preferHeader.ContinueOnError.Should().BeFalse();
+ this.requestMessage.GetHeader(PreferHeaderName).Should().BeNull();
+ }
+
+ [TestMethod]
+ public void SetMaxPageSizeShouldAppendHeader()
+ {
+ const int MaxPageSize = 10;
+ this.preferHeader.MaxPageSize = MaxPageSize;
+ this.preferHeader.MaxPageSize.Should().Be(MaxPageSize);
+ this.requestMessage.GetHeader(PreferHeaderName).Should().Be(string.Format("{0}={1}", MaxPageSizePreference, MaxPageSize));
+ }
+
+ [TestMethod]
+ public void SetMaxPageSizeToNullShouldClearHeader()
+ {
+ this.preferHeader.MaxPageSize = null;
+ this.preferHeader.MaxPageSize.Should().Be(null);
+ this.requestMessage.GetHeader(PreferHeaderName).Should().BeNull();
+ }
+
+ [TestMethod]
+ public void ReturnMaxPageSizeOfBadIntergerFormatShouldThrow()
+ {
+ this.requestMessage.SetHeader(PreferHeaderName, string.Format("{0}=abc", MaxPageSizePreference));
+ this.preferHeader = new ODataPreferenceHeader(this.requestMessage);
+ int? maxPageSize;
+ Action test = () => maxPageSize = this.preferHeader.MaxPageSize;
+ test.ShouldThrow().WithMessage("Input string was not in a correct format.");
+ }
+
+ [TestMethod]
+ public void SetTrackChangesToTrueShouldAppendHeader()
+ {
+ this.preferHeader.TrackChanges = true;
+ this.preferHeader.TrackChanges.Should().BeTrue();
+ this.requestMessage.GetHeader(PreferHeaderName).Should().Be(TrackChangesPreference);
+ }
+
+ [TestMethod]
+ public void SetTrackChangesToFalseShouldClearHeader()
+ {
+ this.preferHeader.TrackChanges = false;
+ this.preferHeader.TrackChanges.Should().BeFalse();
+ this.requestMessage.GetHeader(PreferHeaderName).Should().BeNull();
+ }
}
}