public void PreferHeader_Server() { DSPMetadata metadata = PreferHeader_CreateMetadata(); TestUtil.RunCombinations( new[] { typeof(IDataServiceHost), typeof(IDataServiceHost2) }, new[] { ODataProtocolVersion.V4 }, (hostInterfaceType, maxProtocolVersion) => { DSPSelfmodifyingResource existingItem = new DSPSelfmodifyingResource(metadata.GetResourceType("Item")); existingItem.SetRawValue("ID", 0); existingItem.SetRawValue("ETagProperty", 1); DSPSelfmodifyingResource existingStream = new DSPSelfmodifyingResource(metadata.GetResourceType("Stream")); existingStream.SetRawValue("ID", 0); existingStream.SetRawValue("ETagProperty", 1); bool supportsMR = hostInterfaceType != typeof(IDataServiceHost); DSPServiceDefinition service = this.PreferHeader_CreateService(metadata, existingItem, null, existingStream, null); service.HostInterfaceType = hostInterfaceType; service.DataServiceBehavior.MaxProtocolVersion = maxProtocolVersion; using (TestWebRequest request = service.CreateForInProcess()) { XDocument existingItemAtom = UnitTestsUtil.GetResponseAsAtomXLinq(request, "/Items(0)", "application/atom+xml,application/xml"); XDocument existingStreamAtom = !supportsMR ? null : UnitTestsUtil.GetResponseAsAtomXLinq(request, "/Streams(0)", "application/atom+xml,application/xml"); IEnumerable<string> httpMethods = new string[] { "POST", "POSTMR", "PUT", "PATCH" }; TestUtil.RunCombinations( new string[] { null, "return=representation", "return=minimal", "ReTURN=RePrESenTaTioN", "foo" }, httpMethods, new string[] { UnitTestsUtil.AtomFormat }, (preferHeader, httpMethod, format) => { // Skip MR verification since we use MRs in that entity and as such the request would not work without support on the server if (httpMethod == "POSTMR" && !supportsMR) { return; } service.ClearChanges(); request.RequestVersion = "4.0;"; request.RequestMaxVersion = "4.0;"; request.Accept = "application/atom+xml,application/xml"; request.RequestHeaders["Prefer"] = preferHeader; XDocument existingAtom = httpMethod == "POSTMR" ? existingStreamAtom : existingItemAtom; DSPSelfmodifyingResource existingResource = httpMethod == "POSTMR" ? existingStream : existingItem; this.PreferHeader_SetupRequest(request, httpMethod, format, existingAtom, existingResource, (inputAtom) => { var triggerModification = inputAtom.Root.Descendants(UnitTestsUtil.MetadataNamespace + "properties").First().Element(UnitTestsUtil.DataNamespace + "TriggerModification"); triggerModification.Attributes(UnitTestsUtil.MetadataNamespace + "null").Remove(); triggerModification.Value = "trigger" + existingItem.GetETag().Replace('"', '_'); }); bool serviceAllowsPreferHeader = hostInterfaceType == typeof(IDataServiceHost2); bool? effectiveResponsePreference; this.PreferHeader_ShouldContainResponseBody(request, serviceAllowsPreferHeader, out effectiveResponsePreference); TestUtil.RunCatching(request.SendRequest); DSPSelfmodifyingResource returnedItem; if (httpMethod == "POST" || httpMethod == "POSTMR") { returnedItem = service.CurrentDataSource.GetResourceSetEntities(httpMethod == "POSTMR" ? "Streams" : "Items").OfType<DSPSelfmodifyingResource>().First(r => (int)r.GetValue("ID") == 1); } else { returnedItem = existingResource; } this.PreferHeader_VerifyResponse(request, request.ServiceRoot.ToString(), serviceAllowsPreferHeader, (response) => { if (httpMethod != "POSTMR") // with POST MR the ETagProperty will not be updated since the payload didn't set any properties (it's just the stream) { string etagPropertyValue = returnedItem.GetValue("ETagProperty").ToString(); XElement etagPropertyElement = response.Root.Descendants(UnitTestsUtil.MetadataNamespace + "properties").First().Element(UnitTestsUtil.DataNamespace + "ETagProperty"); Assert.AreEqual(etagPropertyValue, etagPropertyElement.Value, "The updated value was not included in the response."); } }); Assert.AreEqual(returnedItem.GetETag(), request.ResponseETag, "The response ETag does not match the current ETag value on the server."); }); } }); }