/// <summary> /// Gets the response for this request. /// </summary> /// <returns>The response message.</returns> /// <remarks> /// This method is not part of the IODataRequestMessage interface. It's here to make the usage of these classes easier. /// It also handles OData errors by recognizing them and parsing them. /// Each implementation of the interfaces is expected to provide its own way to create the instances and or get them somewhere. /// </remarks> public IODataResponseMessage GetResponse() { try { return(new ClientHttpResponseMessage((HttpWebResponse)this.webRequest.GetResponse())); } catch (WebException webException) { if (webException.Response != null) { // If there is an error response, try to read it. IODataResponseMessage errorResponseMessage = new ClientHttpResponseMessage((HttpWebResponse)webException.Response); using (ODataMessageReader messageReader = new ODataMessageReader(errorResponseMessage)) { // The payload kind detection will determine if the payload is an error by looking at the content type (and possibly even the payload). if (messageReader.DetectPayloadKind().Any(payloadKindDetectionResult => payloadKindDetectionResult.PayloadKind == ODataPayloadKind.Error)) { // Construct the error message by concatenating all the error messages (including the inner ones). // Makes it easier to debug problems. ODataError error = messageReader.ReadError(); // If it is an error throw the ODataErrorException, it's easier to recognize and also read. throw new ODataErrorException(CreateODataErrorExceptionMessage(error), error); } } } throw; } }
/// <summary> /// Creates an <see cref="ODataMessageReader"/> for a given message and context using /// WCF DS client settings. /// </summary> /// <param name="responseMessage">The response message</param> /// <param name="responseInfo">The response context</param> /// <param name="payloadKind">Type of the message.</param> /// <returns>The message reader.</returns> protected static ODataMessageReader CreateODataMessageReader(IODataResponseMessage responseMessage, ResponseInfo responseInfo, ref ODataPayloadKind payloadKind) { ODataMessageReaderSettings settings = responseInfo.ReadHelper.CreateSettings(); ODataMessageReader odataMessageReader = responseInfo.ReadHelper.CreateReader(responseMessage, settings); if (payloadKind == ODataPayloadKind.Unsupported) { var payloadKinds = odataMessageReader.DetectPayloadKind().ToList(); if (payloadKinds.Count == 0) { throw DSClient.Error.InvalidOperation(DSClient.Strings.AtomMaterializer_InvalidResponsePayload(XmlConstants.DataWebNamespace)); } // Pick the first payload kind detected by ODataLib and use that to parse the exception. // The only exception being payload with entity reference link(s). If one of the payload kinds // is reference links, then we need to give preference to reference link payloads. ODataPayloadKindDetectionResult detectionResult = payloadKinds.FirstOrDefault(k => k.PayloadKind == ODataPayloadKind.EntityReferenceLink || k.PayloadKind == ODataPayloadKind.EntityReferenceLinks); if (detectionResult == null) { detectionResult = payloadKinds.First(); } if (detectionResult.Format != ODataFormat.Json && detectionResult.Format != ODataFormat.RawValue) { throw DSClient.Error.InvalidOperation(DSClient.Strings.AtomMaterializer_InvalidContentTypeEncountered(responseMessage.GetHeader(XmlConstants.HttpContentType))); } payloadKind = detectionResult.PayloadKind; } return(odataMessageReader); }
public async Task <ODataResponse> GetResponseAsync(IODataResponseMessageAsync responseMessage) { var readerSettings = new ODataMessageReaderSettings(); // TODO ODataLib7 if (_session.Settings.IgnoreUnmappedProperties) { readerSettings.Validations &= ~ValidationKinds.ThrowOnUndeclaredPropertyForNonOpenType; } readerSettings.MessageQuotas.MaxReceivedMessageSize = Int32.MaxValue; readerSettings.ShouldIncludeAnnotation = x => _session.Settings.IncludeAnnotationsInResults; using (var messageReader = new ODataMessageReader(responseMessage, readerSettings, _model)) { var payloadKind = messageReader.DetectPayloadKind(); if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Error)) { return(ODataResponse.FromStatusCode(responseMessage.StatusCode)); } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Value)) { if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Collection)) { throw new NotImplementedException(); } else { return(ODataResponse.FromValueStream(await responseMessage.GetStreamAsync().ConfigureAwait(false), responseMessage is ODataBatchOperationResponseMessage)); } } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Batch)) { return(await ReadResponse(messageReader.CreateODataBatchReader()).ConfigureAwait(false)); } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.ResourceSet)) { return(ReadResponse(messageReader.CreateODataResourceSetReader())); } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Collection)) { return(ReadResponse(messageReader.CreateODataCollectionReader())); } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Property)) { if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Resource)) { return(ODataResponse.FromValueStream(await responseMessage.GetStreamAsync().ConfigureAwait(false), responseMessage is ODataBatchOperationResponseMessage)); } else { var property = messageReader.ReadProperty(); return(ODataResponse.FromProperty(property.Name, GetPropertyValue(property.Value))); } } else { return(ReadResponse(messageReader.CreateODataResourceReader())); } } }
public async Task <ODataResponse> GetResponseAsync(IODataResponseMessageAsync responseMessage, bool includeResourceTypeInEntryProperties = false) #endif { var readerSettings = new ODataMessageReaderSettings(); readerSettings.MessageQuotas.MaxReceivedMessageSize = Int32.MaxValue; using (var messageReader = new ODataMessageReader(responseMessage, readerSettings, _model)) { var payloadKind = messageReader.DetectPayloadKind(); if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Error)) { return(ODataResponse.FromStatusCode(responseMessage.StatusCode)); } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Value)) { if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Collection)) { throw new NotImplementedException(); } else { #if SILVERLIGHT var text = Utils.StreamToString(responseMessage.GetStream()); #else var text = Client.Utils.StreamToString(await responseMessage.GetStreamAsync()); #endif return(ODataResponse.FromFeed(new[] { new Dictionary <string, object>() { { FluentCommand.ResultLiteral, text } } })); } } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Batch)) { return(await ReadResponse(messageReader.CreateODataBatchReader(), includeResourceTypeInEntryProperties)); } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Feed)) { return(ReadResponse(messageReader.CreateODataFeedReader(), includeResourceTypeInEntryProperties)); } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Collection)) { return(ReadResponse(messageReader.CreateODataCollectionReader(), includeResourceTypeInEntryProperties)); } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Property)) { var property = messageReader.ReadProperty(); return(ODataResponse.FromFeed(new[] { new Dictionary <string, object>() { { property.Name ?? FluentCommand.ResultLiteral, GetPropertyValue(property.Value) } } })); } else { return(ReadResponse(messageReader.CreateODataEntryReader(), includeResourceTypeInEntryProperties)); } } }
public async Task <ODataResponse> GetResponseAsync(IODataResponseMessageAsync responseMessage) { if (responseMessage.StatusCode == (int)HttpStatusCode.NoContent) { return(ODataResponse.FromStatusCode(TypeCache, responseMessage.StatusCode, responseMessage.Headers)); } var readerSettings = _session.ToReaderSettings(); using (var messageReader = new ODataMessageReader(responseMessage, readerSettings, _model)) { var payloadKind = messageReader.DetectPayloadKind().ToList(); if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Error)) { return(ODataResponse.FromStatusCode(TypeCache, responseMessage.StatusCode, responseMessage.Headers)); } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Value)) { if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Collection)) { throw new NotImplementedException(); } else { return(ODataResponse.FromValueStream(TypeCache, await responseMessage.GetStreamAsync().ConfigureAwait(false), responseMessage is ODataBatchOperationResponseMessage)); } } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Batch)) { return(await ReadResponse(messageReader.CreateODataBatchReader()).ConfigureAwait(false)); } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.ResourceSet)) { return(ReadResponse(messageReader.CreateODataResourceSetReader(), responseMessage)); } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Collection)) { return(ReadResponse(messageReader.CreateODataCollectionReader())); } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Property)) { if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Resource)) { return(ReadResponse(messageReader.CreateODataResourceReader(), responseMessage)); } else { var property = messageReader.ReadProperty(); return(ODataResponse.FromProperty(TypeCache, property.Name, GetPropertyValue(property.Value))); } } else { return(ReadResponse(messageReader.CreateODataResourceReader(), responseMessage)); } } }
public async Task<ODataResponse> GetResponseAsync(IODataResponseMessageAsync responseMessage, bool includeResourceTypeInEntryProperties = false) { var readerSettings = new ODataMessageReaderSettings(); readerSettings.MessageQuotas.MaxReceivedMessageSize = Int32.MaxValue; using (var messageReader = new ODataMessageReader(responseMessage, readerSettings, _model)) { var payloadKind = messageReader.DetectPayloadKind(); if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Error)) { return ODataResponse.FromStatusCode(responseMessage.StatusCode); } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Value)) { if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Collection)) { throw new NotImplementedException(); } else { var text = Utils.StreamToString(await responseMessage.GetStreamAsync()); return ODataResponse.FromFeed(new[] { new Dictionary<string, object>() { { FluentCommand.ResultLiteral, text } } }); } } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Batch)) { return await ReadResponse(messageReader.CreateODataBatchReader(), includeResourceTypeInEntryProperties); } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Feed)) { return ReadResponse(messageReader.CreateODataFeedReader(), includeResourceTypeInEntryProperties); } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Collection)) { return ReadResponse(messageReader.CreateODataCollectionReader(), includeResourceTypeInEntryProperties); } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Property)) { var property = messageReader.ReadProperty(); return ODataResponse.FromFeed(new[] { new Dictionary<string, object>() { { property.Name ?? FluentCommand.ResultLiteral, GetPropertyValue(property.Value) } } }); } else { return ReadResponse(messageReader.CreateODataEntryReader(), includeResourceTypeInEntryProperties); } } }
public async Task <ODataResponse> GetResponseAsync(IODataResponseMessageAsync responseMessage) { var readerSettings = new ODataMessageReaderSettings(); readerSettings.MessageQuotas.MaxReceivedMessageSize = Int32.MaxValue; readerSettings.ShouldIncludeAnnotation = x => _session.Settings.IncludeAnnotationsInResults; using (var messageReader = new ODataMessageReader(responseMessage, readerSettings, _model)) { var payloadKind = messageReader.DetectPayloadKind(); if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Error)) { return(ODataResponse.FromStatusCode(responseMessage.StatusCode)); } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Value)) { if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Collection)) { throw new NotImplementedException(); } else { return(ODataResponse.FromValueStream(await responseMessage.GetStreamAsync(), responseMessage is ODataBatchOperationResponseMessage)); } } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Batch)) { return(await ReadResponse(messageReader.CreateODataBatchReader())); } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Feed)) { return(ReadResponse(messageReader.CreateODataFeedReader())); } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Collection)) { return(ReadResponse(messageReader.CreateODataCollectionReader())); } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Property)) { var property = messageReader.ReadProperty(); return(ODataResponse.FromProperty(property.Name, GetPropertyValue(property.Value))); } else { return(ReadResponse(messageReader.CreateODataEntryReader())); } } }
protected static ODataMessageReader CreateODataMessageReader(IODataResponseMessage responseMessage, ResponseInfo responseInfo, ref ODataPayloadKind payloadKind) { ODataMessageReaderSettings settings = responseInfo.ReadHelper.CreateSettings(ReadingEntityInfo.BufferAndCacheEntryPayload); ODataMessageReader odataMessageReader = responseInfo.ReadHelper.CreateReader(responseMessage, settings); if (payloadKind == ODataPayloadKind.Unsupported) { var payloadKinds = odataMessageReader.DetectPayloadKind().ToList(); if (payloadKinds.Count == 0) { throw DSClient.Error.InvalidOperation(DSClient.Strings.AtomMaterializer_InvalidResponsePayload(responseInfo.DataNamespace)); } // Pick the first payload kind detected by ODataLib and use that to parse the exception. // The only exception being payload with entity reference link(s). If one of the payload kinds // is reference links, then we need to give preference to reference link payloads. ODataPayloadKindDetectionResult detectionResult = payloadKinds.FirstOrDefault(k => k.PayloadKind == ODataPayloadKind.EntityReferenceLink || k.PayloadKind == ODataPayloadKind.EntityReferenceLinks); if (detectionResult == null) { ODataVersion dataServiceVersion = responseMessage.GetDataServiceVersion(CommonUtil.ConvertToODataVersion(responseInfo.MaxProtocolVersion)); // if its a collection or a Property we should choose collection if its less than V3, this enables older service operations on Execute if (dataServiceVersion < ODataVersion.V3 && payloadKinds.Any(pk => pk.PayloadKind == ODataPayloadKind.Property) && payloadKinds.Any(pk => pk.PayloadKind == ODataPayloadKind.Collection)) { detectionResult = payloadKinds.Single(pk => pk.PayloadKind == ODataPayloadKind.Collection); } else { detectionResult = payloadKinds.First(); } } // Astoria client only supports atom, jsonverbose, jsonlight and raw value payloads. if (detectionResult.Format != ODataFormat.Atom && detectionResult.Format != ODataFormat.VerboseJson && detectionResult.Format != ODataFormat.Json && detectionResult.Format != ODataFormat.RawValue) { throw DSClient.Error.InvalidOperation(DSClient.Strings.AtomMaterializer_InvalidContentTypeEncountered(responseMessage.GetHeader(XmlConstants.HttpContentType))); } payloadKind = detectionResult.PayloadKind; } return(odataMessageReader); }
public async Task<ODataResponse> GetResponseAsync(IODataResponseMessageAsync responseMessage) { var readerSettings = new ODataMessageReaderSettings(); readerSettings.MessageQuotas.MaxReceivedMessageSize = Int32.MaxValue; using (var messageReader = new ODataMessageReader(responseMessage, readerSettings, _model)) { var payloadKind = messageReader.DetectPayloadKind(); if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Error)) { return ODataResponse.FromStatusCode(responseMessage.StatusCode); } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Value)) { if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Collection)) { throw new NotImplementedException(); } else { return ODataResponse.FromValueStream(await responseMessage.GetStreamAsync()); } } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Batch)) { return await ReadResponse(messageReader.CreateODataBatchReader()); } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Feed)) { return ReadResponse(messageReader.CreateODataFeedReader()); } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Collection)) { return ReadResponse(messageReader.CreateODataCollectionReader()); } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Property)) { var property = messageReader.ReadProperty(); return ODataResponse.FromProperty(property.Name, GetPropertyValue(property.Value)); } else { return ReadResponse(messageReader.CreateODataEntryReader()); } } }
private static ODataResult GetODataResult(ODataMessageReader messageReader) { List <ODataPayloadKindDetectionResult> payloadKinds = messageReader.DetectPayloadKind().ToList(); if (payloadKinds.Count > 0) { switch (payloadKinds[0].PayloadKind) { case ODataPayloadKind.Feed: return(new FeedODataResult(messageReader.CreateODataFeedReader())); case ODataPayloadKind.Entry: return(new FeedODataResult(messageReader.CreateODataEntryReader())); } throw new InvalidOperationException("unsupported payload kind " + payloadKinds[0].PayloadKind); } throw new InvalidOperationException("unknown payload kind"); }
protected static ODataMessageReader CreateODataMessageReader(IODataResponseMessage responseMessage, System.Data.Services.Client.ResponseInfo responseInfo, bool projectionQuery, ref ODataPayloadKind payloadKind) { Func <ODataEntry, XmlReader, Uri, XmlReader> entryXmlCustomizer = null; if (responseInfo.HasReadingEntityHandlers) { entryXmlCustomizer = new Func <ODataEntry, XmlReader, Uri, XmlReader>(ODataMaterializer.EntryXmlCustomizer); } ODataMessageReaderSettings settings = WebUtil.CreateODataMessageReaderSettings(responseInfo, entryXmlCustomizer, projectionQuery); ODataMessageReader reader = new ODataMessageReader(responseMessage, settings, ClientEdmModel.GetModel(responseInfo.MaxProtocolVersion)); if (payloadKind == ODataPayloadKind.Unsupported) { List <ODataPayloadKindDetectionResult> source = reader.DetectPayloadKind().ToList <ODataPayloadKindDetectionResult>(); if (source.Count == 0) { throw System.Data.Services.Client.Error.InvalidOperation(System.Data.Services.Client.Strings.AtomMaterializer_InvalidResponsePayload(responseInfo.DataNamespace)); } ODataPayloadKindDetectionResult result = source.FirstOrDefault <ODataPayloadKindDetectionResult>(delegate(ODataPayloadKindDetectionResult k) { if (k.PayloadKind != ODataPayloadKind.EntityReferenceLink) { return(k.PayloadKind == ODataPayloadKind.EntityReferenceLinks); } return(true); }); if (result == null) { result = source.First <ODataPayloadKindDetectionResult>(); } if ((result.Format != ODataFormat.Atom) && (result.Format != ODataFormat.RawValue)) { throw System.Data.Services.Client.Error.InvalidOperation(System.Data.Services.Client.Strings.AtomMaterializer_InvalidContentTypeEncountered(responseMessage.GetHeader("Content-Type"))); } payloadKind = result.PayloadKind; } return(reader); }
public void DetectPayloadKind() { var responseMessage = new Microsoft.Test.OData.Tests.Client.Common.InMemoryMessage(); responseMessage.Stream = new MemoryStream(Encoding.UTF8.GetBytes(@"<?xml version=""1.0"" encoding=""utf-8"" standalone=""yes""?> <feed xml:base=""http://localhost:12367/Test/Data.ashx/UnitedNations/Demographic/v1/"" xmlns:d=""http://docs.oasis-open.org/odata/ns/data"" xmlns:m=""http://docs.oasis-open.org/odata/ns/metadata"" xmlns=""http://www.w3.org/2005/Atom""> <title type=""text"">DataSeries</title> <id>http://localhost:12367/Test/Data.ashx/UnitedNations/Demographic/v1/DataSeries</id> <updated>2013-06-11T02:31:42Z</updated> <link rel=""self"" title=""DataSeries"" href=""DataSeries"" /> <entry> <id>http://localhost:12367/Test/Data.ashx/UnitedNations/Demographic/v1/DataSeries('1')</id> <title type=""text""></title> <updated>2013-06-11T02:31:42Z</updated> <author> <name /> </author> <link rel=""edit"" title=""DataSeries"" href=""DataSeries('1')"" /> <category term=""UnitedNations.Demographic.DataSeries"" scheme=""http://docs.oasis-open.org/odata/ns/scheme"" /> <content type=""application/xml""> <m:properties> <d:Id>1</d:Id> <d:DataSetId>POP</d:DataSetId> <d:Name>Population by urban/rural residence</d:Name> </m:properties> </content> </entry> </feed> ")); responseMessage.SetHeader("Content-Type", "application/atom+xml"); using (var messageReader = new ODataMessageReader(responseMessage as IODataResponseMessage, new ODataMessageReaderSettings())) { var reader = messageReader.DetectPayloadKind(); } }
public void DetectPayloadKind() { var responseMessage = new Microsoft.Test.OData.Tests.Client.Common.InMemoryMessage(); responseMessage.Stream = new MemoryStream(Encoding.UTF8.GetBytes(@"<?xml version=""1.0"" encoding=""utf-8"" standalone=""yes""?> <feed xml:base=""http://localhost:12367/Test/Data.ashx/UnitedNations/Demographic/v1/"" xmlns:d=""http://docs.oasis-open.org/odata/ns/data"" xmlns:m=""http://docs.oasis-open.org/odata/ns/metadata"" xmlns=""http://www.w3.org/2005/Atom""> <title type=""text"">DataSeries</title> <id>http://localhost:12367/Test/Data.ashx/UnitedNations/Demographic/v1/DataSeries</id> <updated>2013-06-11T02:31:42Z</updated> <link rel=""self"" title=""DataSeries"" href=""DataSeries"" /> <entry> <id>http://localhost:12367/Test/Data.ashx/UnitedNations/Demographic/v1/DataSeries('1')</id> <title type=""text""></title> <updated>2013-06-11T02:31:42Z</updated> <author> <name /> </author> <link rel=""edit"" title=""DataSeries"" href=""DataSeries('1')"" /> <category term=""UnitedNations.Demographic.DataSeries"" scheme=""http://docs.oasis-open.org/odata/ns/scheme"" /> <content type=""application/xml""> <m:properties> <d:Id>1</d:Id> <d:DataSetId>POP</d:DataSetId> <d:Name>Population by urban/rural residence</d:Name> </m:properties> </content> </entry> </feed> ")); responseMessage.SetHeader("Content-Type", "application/atom+xml"); using (var messageReader = new ODataMessageReader(responseMessage as IODataResponseMessage, new ODataMessageReaderSettings())) { var reader = messageReader.DetectPayloadKind(); } }
public async Task <ODataResponse> GetResponseAsync(IODataResponseMessageAsync responseMessage) #endif { var readerSettings = new ODataMessageReaderSettings(); readerSettings.MessageQuotas.MaxReceivedMessageSize = Int32.MaxValue; using (var messageReader = new ODataMessageReader(responseMessage, readerSettings, _model)) { var payloadKind = messageReader.DetectPayloadKind(); if (payloadKind.Any(x => x.PayloadKind != ODataPayloadKind.Property)) { _hasResponse = true; } if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Error)) { return(ODataResponse.FromStatusCode(responseMessage.StatusCode)); } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Value)) { if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Collection)) { throw new NotImplementedException(); } else { #if SILVERLIGHT var stream = responseMessage.GetStream(); #else var stream = await responseMessage.GetStreamAsync(); #endif return(ODataResponse.FromValueStream(stream, responseMessage is ODataBatchOperationResponseMessage)); } } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Batch)) { return(await ReadResponse(messageReader.CreateODataBatchReader())); } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Feed)) { return(ReadResponse(messageReader.CreateODataFeedReader())); } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Collection)) { return(ReadResponse(messageReader.CreateODataCollectionReader())); } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Property)) { var property = messageReader.ReadProperty(); if (property.Value != null && (property.Value.GetType() != typeof(string) || !string.IsNullOrEmpty(property.Value.ToString()))) { _hasResponse = true; } if (_hasResponse) { return(ODataResponse.FromProperty(property.Name, GetPropertyValue(property.Value))); } else { return(ODataResponse.EmptyFeed); } } else { return(ReadResponse(messageReader.CreateODataEntryReader())); } } }
public void ReadFeedWithActionAndFunctionTest() { string payload = "{\"" + "@odata.context\":\"http://example.org/odata.svc/$metadata#EntitySet\"," + "\"#Namespace.Action\":{" + "\"title\":\"ActionTitle\"," + "\"target\":\"http://example.org/odata.svc/DoAction\"" + "}," + "\"#Namespace.Function\":{" + "\"title\":\"FunctionTitle\"," + "\"target\":\"http://example.org/odata.svc/DoFunction\"" + "}," + "\"value\":[" + "{" + "\"ID\":101,\"Name\":\"Alice\"" + "}" + "]" + "}"; InMemoryMessage message = new InMemoryMessage(); message.SetHeader("Content-Type", "application/json;odata.metadata=minimal"); message.Stream = new MemoryStream(Encoding.UTF8.GetBytes(payload)); List<ODataFeed> feedList = new List<ODataFeed>(); using (var messageReader = new ODataMessageReader((IODataResponseMessage)message, null, ModelWithFunction)) { messageReader.DetectPayloadKind().Single().PayloadKind.Should().Be(ODataPayloadKind.Feed); var reader = messageReader.CreateODataFeedReader(); while (reader.Read()) { switch (reader.State) { case ODataReaderState.FeedEnd: feedList.Add(reader.Item as ODataFeed); break; } } } ODataFeed feed = feedList[0]; feed.Actions.Count().Should().Be(1); feed.Functions.Count().Should().Be(1); }
public async Task <ODataResponse> GetResponseAsync(IODataResponseMessageAsync responseMessage) { var readerSettings = new ODataMessageReaderSettings(); if (_session.Settings.IgnoreUnmappedProperties) { readerSettings.UndeclaredPropertyBehaviorKinds = ODataUndeclaredPropertyBehaviorKinds.IgnoreUndeclaredValueProperty; } readerSettings.MessageQuotas.MaxReceivedMessageSize = Int32.MaxValue; readerSettings.ShouldIncludeAnnotation = x => _session.Settings.IncludeAnnotationsInResults; using (var messageReader = new ODataMessageReader(responseMessage, readerSettings, _model)) { var payloadKind = messageReader.DetectPayloadKind(); if (payloadKind.Any(x => x.PayloadKind != ODataPayloadKind.Property)) { _hasResponse = true; } if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Error)) { return(ODataResponse.FromStatusCode(responseMessage.StatusCode)); } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Value)) { if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Collection)) { throw new NotImplementedException(); } else { var stream = await responseMessage.GetStreamAsync().ConfigureAwait(false); return(ODataResponse.FromValueStream(stream, responseMessage is ODataBatchOperationResponseMessage)); } } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Batch)) { return(await ReadResponse(messageReader.CreateODataBatchReader()).ConfigureAwait(false)); } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Feed)) { return(ReadResponse(messageReader.CreateODataFeedReader())); } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Collection)) { return(ReadResponse(messageReader.CreateODataCollectionReader())); } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Property)) { var property = messageReader.ReadProperty(); if (property.Value != null && (property.Value.GetType() != typeof(string) || !string.IsNullOrEmpty(property.Value.ToString()))) { _hasResponse = true; } if (_hasResponse) { return(ODataResponse.FromProperty(property.Name, GetPropertyValue(property.Value))); } else { return(ODataResponse.EmptyFeed); } } else { return(ReadResponse(messageReader.CreateODataEntryReader())); } } }
protected static ODataMessageReader CreateODataMessageReader(IODataResponseMessage responseMessage, System.Data.Services.Client.ResponseInfo responseInfo, bool projectionQuery, ref ODataPayloadKind payloadKind) { Func<ODataEntry, XmlReader, Uri, XmlReader> entryXmlCustomizer = null; if (responseInfo.HasReadingEntityHandlers) { entryXmlCustomizer = new Func<ODataEntry, XmlReader, Uri, XmlReader>(ODataMaterializer.EntryXmlCustomizer); } ODataMessageReaderSettings settings = WebUtil.CreateODataMessageReaderSettings(responseInfo, entryXmlCustomizer, projectionQuery); ODataMessageReader reader = new ODataMessageReader(responseMessage, settings, ClientEdmModel.GetModel(responseInfo.MaxProtocolVersion)); if (payloadKind == ODataPayloadKind.Unsupported) { List<ODataPayloadKindDetectionResult> source = reader.DetectPayloadKind().ToList<ODataPayloadKindDetectionResult>(); if (source.Count == 0) { throw System.Data.Services.Client.Error.InvalidOperation(System.Data.Services.Client.Strings.AtomMaterializer_InvalidResponsePayload(responseInfo.DataNamespace)); } ODataPayloadKindDetectionResult result = source.FirstOrDefault<ODataPayloadKindDetectionResult>(delegate (ODataPayloadKindDetectionResult k) { if (k.PayloadKind != ODataPayloadKind.EntityReferenceLink) { return k.PayloadKind == ODataPayloadKind.EntityReferenceLinks; } return true; }); if (result == null) { result = source.First<ODataPayloadKindDetectionResult>(); } if ((result.Format != ODataFormat.Atom) && (result.Format != ODataFormat.RawValue)) { throw System.Data.Services.Client.Error.InvalidOperation(System.Data.Services.Client.Strings.AtomMaterializer_InvalidContentTypeEncountered(responseMessage.GetHeader("Content-Type"))); } payloadKind = result.PayloadKind; } return reader; }
public async Task <ODataResponse> GetResponseAsync(IODataResponseMessageAsync responseMessage) { if (responseMessage.StatusCode == (int)HttpStatusCode.NoContent) { return(ODataResponse.FromStatusCode(TypeCache, responseMessage.StatusCode, responseMessage.Headers)); } var readerSettings = _session.ToReaderSettings(); using var messageReader = new ODataMessageReader(responseMessage, readerSettings, _model); var payloadKind = messageReader.DetectPayloadKind(); if (payloadKind.Any(x => x.PayloadKind != ODataPayloadKind.Property)) { _hasResponse = true; } if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Error)) { return(ODataResponse.FromStatusCode(TypeCache, responseMessage.StatusCode, responseMessage.Headers)); } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Value)) { if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Collection)) { throw new NotImplementedException(); } else { var stream = await responseMessage.GetStreamAsync().ConfigureAwait(false); return(ODataResponse.FromValueStream(TypeCache, stream, responseMessage is ODataBatchOperationResponseMessage)); } } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Batch)) { return(await ReadResponse(messageReader.CreateODataBatchReader()).ConfigureAwait(false)); } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Feed)) { return(ReadResponse(messageReader.CreateODataFeedReader(), responseMessage)); } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Collection)) { return(ReadResponse(messageReader.CreateODataCollectionReader())); } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Property)) { var property = messageReader.ReadProperty(); if (property.Value != null && (property.Value.GetType() != typeof(string) || !string.IsNullOrEmpty(property.Value.ToString()))) { _hasResponse = true; } if (_hasResponse) { return(ODataResponse.FromProperty(TypeCache, property.Name, GetPropertyValue(property.Value))); } else { return(ODataResponse.EmptyFeeds(TypeCache)); } } else { return(ReadResponse(messageReader.CreateODataEntryReader(), responseMessage)); } }
public async Task<ODataResponse> GetResponseAsync(IODataResponseMessageAsync responseMessage) #endif { var readerSettings = new ODataMessageReaderSettings(); readerSettings.MessageQuotas.MaxReceivedMessageSize = Int32.MaxValue; using (var messageReader = new ODataMessageReader(responseMessage, readerSettings, _model)) { var payloadKind = messageReader.DetectPayloadKind(); if (payloadKind.Any(x => x.PayloadKind != ODataPayloadKind.Property)) _hasResponse = true; if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Error)) { return ODataResponse.FromStatusCode(responseMessage.StatusCode); } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Value)) { if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Collection)) { throw new NotImplementedException(); } else { #if SILVERLIGHT var stream = responseMessage.GetStream(); #else var stream = await responseMessage.GetStreamAsync(); #endif return ODataResponse.FromValueStream(stream); } } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Batch)) { return await ReadResponse(messageReader.CreateODataBatchReader()); } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Feed)) { return ReadResponse(messageReader.CreateODataFeedReader()); } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Collection)) { return ReadResponse(messageReader.CreateODataCollectionReader()); } else if (payloadKind.Any(x => x.PayloadKind == ODataPayloadKind.Property)) { var property = messageReader.ReadProperty(); if (property.Value != null && (property.Value.GetType() != typeof(string) || !string.IsNullOrEmpty(property.Value.ToString()))) _hasResponse = true; if (_hasResponse) { return ODataResponse.FromProperty(property.Name, GetPropertyValue(property.Value)); } else { return ODataResponse.EmptyFeed; } } else { return ReadResponse(messageReader.CreateODataEntryReader()); } } }
private static ODataResult GetODataResult(ODataMessageReader messageReader) { List<ODataPayloadKindDetectionResult> payloadKinds = messageReader.DetectPayloadKind().ToList(); if (payloadKinds.Count > 0) { switch (payloadKinds[0].PayloadKind) { case ODataPayloadKind.Feed: return new FeedODataResult(messageReader.CreateODataFeedReader()); case ODataPayloadKind.Entry: return new FeedODataResult(messageReader.CreateODataEntryReader()); } throw new InvalidOperationException("unsupported payload kind " + payloadKinds[0].PayloadKind); } throw new InvalidOperationException("unknown payload kind"); }
public async Task CanHandleAbsoluteAndRelativeUrlsJSON() { // Arrange var requestUri = string.Format("{0}/UnbufferedBatch/$batch", this.BaseAddress); Uri address = new Uri(this.BaseAddress, UriKind.Absolute); string relativeToServiceRootUri = "UnbufferedBatchCustomer"; string relativeToHostUri = address.LocalPath.TrimEnd(new char[] { '/' }) + "/UnbufferedBatch/UnbufferedBatchCustomer"; string absoluteUri = this.BaseAddress + "/UnbufferedBatch/UnbufferedBatchCustomer"; // Act HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, requestUri); HttpContent content = new StringContent(@" { ""requests"":[ { ""id"": ""2"", ""atomicityGroup"": ""transaction"", ""method"": ""post"", ""url"": """ + relativeToServiceRootUri + @""", ""headers"": { ""content-type"": ""application/json"", ""Accept"": ""application/json"", ""odata-version"": ""4.0"" }, ""body"": {'Id':11,'Name':'MyName11'} }, { ""id"": ""3"", ""atomicityGroup"": ""transaction"", ""method"": ""post"", ""url"": """ + relativeToHostUri + @""", ""headers"": { ""content-type"": ""application/json"", ""Accept"": ""application/json"", ""odata-version"": ""4.0"" }, ""body"": {'Id':12,'Name':'MyName12'} }, { ""id"": ""4"", ""atomicityGroup"": ""transaction"", ""method"": ""post"", ""url"": """ + absoluteUri + @""", ""headers"": { ""content-type"": ""application/json"", ""Accept"": ""application/json"", ""odata-version"": ""4.0"" }, ""body"": {'Id':13,'Name':'MyName13'} } ] }"); content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json"); request.Content = content; HttpResponseMessage response = await Client.SendAsync(request); // Assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal("application/json", response.Content.Headers.ContentType.MediaType); var stream = await response.Content.ReadAsStreamAsync(); IODataResponseMessage odataResponseMessage = new ODataMessageWrapper(stream, response.Content.Headers); int subResponseCount = 0; var model = GetEdmModel(new ODataConventionModelBuilder()); using (var messageReader = new ODataMessageReader(odataResponseMessage, new ODataMessageReaderSettings(), model)) { var batchReader = messageReader.CreateODataBatchReader(); while (batchReader.Read()) { switch (batchReader.State) { case ODataBatchReaderState.Operation: var operationMessage = batchReader.CreateOperationResponseMessage(); subResponseCount++; Assert.Equal(201, operationMessage.StatusCode); Assert.Contains("application/json", operationMessage.Headers.Single(h => String.Equals(h.Key, "Content-Type", StringComparison.OrdinalIgnoreCase)).Value); using (var innerMessageReader = new ODataMessageReader(operationMessage, new ODataMessageReaderSettings(), model)) { innerMessageReader.DetectPayloadKind().FirstOrDefault(); } break; } } } Assert.Equal(3, subResponseCount); }