private static ODataVersion?GetODataVersion(HttpHeaders headers, params string[] headerNames) { foreach (string headerName in headerNames) { IEnumerable <string> values; if (headers.TryGetValues(headerName, out values)) { string value = values.FirstOrDefault(); if (value != null) { string trimmedValue = value.Trim(' ', ';'); try { return(ODataUtils.StringToODataVersion(trimmedValue)); } catch (ODataException) { // Parsing ODataVersion failed, try next header } } } } return(null); }
/// <inheritdoc/> public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType) { // Determine the content type or let base class handle it. MediaTypeHeaderValue newMediaType = null; if (ODataOutputFormatterHelper.TryGetContentHeader(type, mediaType, out newMediaType)) { headers.ContentType = newMediaType; } else { // This is the case when a user creates a new ObjectContent<T> passing in a null mediaType base.SetDefaultContentHeaders(type, headers, mediaType); } // Set the character set. IEnumerable <string> acceptCharsetValues = Request.Headers.AcceptCharset.Select(cs => cs.Value); string newCharSet = String.Empty; if (ODataOutputFormatterHelper.TryGetCharSet(headers.ContentType, acceptCharsetValues, out newCharSet)) { headers.ContentType.CharSet = newCharSet; } // Add version header. headers.TryAddWithoutValidation( ODataVersionConstraint.ODataServiceVersionHeader, ODataUtils.ODataVersionToString(_version)); }
private static ODataJsonLightOutputContext CreateJsonLightOutputContext( MemoryStream stream, bool writingResponse = true, bool synchronous = true, bool use6x = false, ODataVersion version = ODataVersion.V4) { var messageInfo = new ODataMessageInfo { MessageStream = new NonDisposingStream(stream), MediaType = new ODataMediaType("application", "json"), Encoding = Encoding.UTF8, IsResponse = writingResponse, IsAsync = !synchronous, Model = EdmCoreModel.Instance }; var settings = new ODataMessageWriterSettings { Version = version }; settings.SetServiceDocumentUri(new Uri("http://odata.org/test")); settings.ShouldIncludeAnnotation = ODataUtils.CreateAnnotationFilter("*"); if (use6x) { settings.LibraryCompatibility = ODataLibraryCompatibility.Version6; } return(new ODataJsonLightOutputContext(messageInfo, settings)); }
public void NonMediaTypeShouldNotHaveDefaultValues() { const string headerName = "Some-Header"; const string headerValue = MimeConstants.MimeApplicationJson; Assert.Equal(headerValue, ODataUtils.AppendDefaultHeaderValue(headerName, headerValue)); }
/// <summary> /// Determines the response format based on the results of content negotiation. /// </summary> /// <param name="payloadKind">The payload kind of the response.</param> /// <param name="acceptableMediaTypes"> /// The acceptable media types used to determine the content type of the message. /// This is a comma separated list of content types as specified in RFC 2616, Section 14.1 /// </param> /// <param name="acceptableCharSets"> /// The acceptable charsets to use to the determine the encoding of the message. /// This is a comma separated list of charsets as specified in RFC 2616, Section 14.2 /// </param> /// <returns>The format the response should use. </returns> internal ODataFormatWithParameters DetermineResponseFormat(ODataPayloadKind payloadKind, string acceptableMediaTypes, string acceptableCharSets) { Debug.Assert(payloadKind != ODataPayloadKind.Unsupported, "kind != ODataPayloadKind.Unsupported"); ContentNegotiationResponseMessage responseMessage = new ContentNegotiationResponseMessage(); ODataMessageWriterSettings settings = new ODataMessageWriterSettings { Version = this.responseVersion }; settings.EnableAtomSupport(); settings.SetContentType(acceptableMediaTypes, acceptableCharSets); try { using (ODataMessageWriter writer = new ODataMessageWriter(responseMessage, settings)) { ODataFormat format = ODataUtils.SetHeadersForPayload(writer, payloadKind); return(new ODataFormatWithParameters(format, responseMessage.ContentType)); } } catch (ODataContentTypeException exception) { if (this.throwIfNoMatch) { throw new DataServiceException(415, null, Microsoft.OData.Service.Strings.DataServiceException_UnsupportedMediaType, null, exception); } return(null); } }
/// <inheritdoc/> public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType) { // call base to validate parameters and set Content-Type header based on mediaType parameter. base.SetDefaultContentHeaders(type, headers, mediaType); headers.TryAddWithoutValidation(ODataServiceVersion, ODataUtils.ODataVersionToString(_version)); }
public void GetVersionUtilTest() { //positive tests this.Assert.AreEqual(ODataUtils.StringToODataVersion(DataServiceVersion4), ODataVersion.V4, "Failed to parse Data Service Version string"); this.Assert.AreEqual(ODataUtils.StringToODataVersion(DataServiceVersion4 + ";"), ODataVersion.V4, "Failed to parse Data Service Version string"); this.Assert.AreEqual(ODataUtils.StringToODataVersion(DataServiceVersion4 + ";anything"), ODataVersion.V4, "Failed to parse Data Service Version string"); this.Assert.AreEqual(ODataUtils.ODataVersionToString(ODataVersion.V4), DataServiceVersion4, "Failed to parse Data Service Version enum"); //negative tests string[] invalidVersionStrings = { "randomstring", "V1.0", "1.5", "randomstring;1.0", "5.0", "1" }; foreach (string s in invalidVersionStrings) { TestExceptionUtils.ExpectedException( this.Assert, () => { ODataUtils.StringToODataVersion(s); }, ODataExpectedExceptions.ODataException("ODataUtils_UnsupportedVersionHeader", s), this.ExceptionVerifier ); } }
public void WritingMultipleInstanceAnnotationInComplexValueShouldWrite() { var complexType = new EdmComplexType("TestNamespace", "Address"); model.AddElement(complexType); settings.ShouldIncludeAnnotation = ODataUtils.CreateAnnotationFilter("*"); var result = this.SetupSerializerAndRunTest(serializer => { var complexValue = new ODataComplexValue { TypeName = "TestNamespace.Address", InstanceAnnotations = new Collection <ODataInstanceAnnotation> { new ODataInstanceAnnotation("Annotation.1", new ODataPrimitiveValue(true)), new ODataInstanceAnnotation("Annotation.2", new ODataPrimitiveValue(123)), new ODataInstanceAnnotation("Annotation.3", new ODataPrimitiveValue("annotation")) } }; var complexTypeRef = new EdmComplexTypeReference(complexType, false); serializer.WriteComplexValue(complexValue, complexTypeRef, false, false, new DuplicatePropertyNamesChecker(false, true)); }); result.Should().Contain("\"@Annotation.1\":true,\"@Annotation.2\":123,\"@Annotation.3\":\"annotation\""); }
/// <inheritdoc/> public virtual async Task <HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken) { IHttpActionResult result = GetInnerActionResult(); var response = await result.ExecuteAsync(cancellationToken); ResultHelpers.AddServiceVersion(response, () => ODataUtils.ODataVersionToString(ResultHelpers.GetODataResponseVersion(Request))); return(response); }
public void CreateInstanceAnnotationsFilterShouldTranslateFilterStringToFunc() { Func <string, bool> filter = ODataUtils.CreateAnnotationFilter("*,-ns.*"); Assert.NotNull(filter); Assert.False(filter("ns.name")); Assert.True(filter("foo.bar")); }
/// <summary> /// Set the HasStream boolean annotation in the EdmType to true. /// </summary> private void SetMediaLinkEntryAnnotation() { Debug.Assert(this.isMediaLinkEntry.HasValue && this.isMediaLinkEntry.Value, "This method must be called if the entity is an MLE"); Debug.Assert(this.EdmType is EdmEntityType, "SetMediaLinkEntryAnnotation must be called for entity types"); // Why is this not a property on ODataEdmTypeAnnotation ?? ODataUtils.SetHasDefaultStream(this.model, (IEdmEntityType)this.EdmType, true); }
public void CreateInstanceAnnotationsFilterShouldTranslateFilterStringToFunc() { Func <string, bool> filter = ODataUtils.CreateAnnotationFilter("*,-ns.*"); filter.Should().NotBeNull(); filter("ns.name").Should().BeFalse(); filter("foo.bar").Should().BeTrue(); }
/// <summary> /// Initializes a new instance of the <see cref="ODataBatchContent"/> class. /// </summary> /// <param name="responses">The batch responses.</param> /// <param name="requestContainer">The dependency injection container for the request.</param> /// <remarks>This signature uses types that are AspNetCore-specific.</remarks> public ODataBatchContent(IEnumerable <ODataBatchResponseItem> responses, IServiceProvider requestContainer) { Initialize(responses, requestContainer); Headers[HeaderNames.ContentType] = String.Format(CultureInfo.InvariantCulture, "multipart/mixed;boundary=batchresponse_{0}", Guid.NewGuid()); ODataVersion version = _writerSettings.Version ?? ODataVersionConstraint.DefaultODataVersion; Headers.Add(ODataVersionConstraint.ODataServiceVersionHeader, ODataUtils.ODataVersionToString(version)); }
protected override ContentFormat GetContentFormat() { if (ODataUtils.GetReadFormat(base.MessageReader) != ODataFormat.VerboseJson) { throw new InvalidOperationException(System.Data.Services.Strings.DataServiceException_GeneralError); } return(ContentFormat.VerboseJson); }
public void CopyConstructorShouldCopyAnnotationFilter() { ODataMessageReaderSettings testSubject = new ODataMessageReaderSettings(); testSubject.ShouldIncludeAnnotation = ODataUtils.CreateAnnotationFilter("namespace.*"); var copy = new ODataMessageReaderSettings(testSubject); copy.ShouldIncludeAnnotation.Should().BeSameAs(testSubject.ShouldIncludeAnnotation); }
/// <inheritdoc/> public async virtual Task ExecuteResultAsync(ActionContext context) { HttpResponse response = context.HttpContext.Response; HttpRequest request = context.HttpContext.Request; IActionResult result = GetInnerActionResult(request); await result.ExecuteResultAsync(context); ResultHelpers.AddServiceVersion(response, () => ODataUtils.ODataVersionToString(ResultHelpers.GetODataResponseVersion(request))); }
internal ResponseBodyWriter(bool hasMoved, IDataService service, IEnumerator queryResults, RequestDescription requestDescription, IODataResponseMessage responseMessage, ODataPayloadKind payloadKind) { this.hasMoved = hasMoved; this.service = service; this.queryResults = queryResults; this.requestDescription = requestDescription; this.responseMessage = responseMessage; this.payloadKind = payloadKind; this.encoding = HttpProcessUtility.EncodingFromAcceptCharset(this.service.OperationContext.Host.RequestAcceptCharSet); if ((((payloadKind == ODataPayloadKind.Entry) || (payloadKind == ODataPayloadKind.Feed)) || ((payloadKind == ODataPayloadKind.Property) || (payloadKind == ODataPayloadKind.Collection))) || (((payloadKind == ODataPayloadKind.EntityReferenceLink) || (payloadKind == ODataPayloadKind.EntityReferenceLinks)) || (((payloadKind == ODataPayloadKind.Error) || (payloadKind == ODataPayloadKind.ServiceDocument)) || (payloadKind == ODataPayloadKind.Parameter)))) { DataServiceHostWrapper host = service.OperationContext.Host; if (WebUtil.GetEffectiveMaxResponseVersion(service.Configuration.DataServiceBehavior.MaxProtocolVersion, host.RequestMaxVersion) > RequestDescription.Version2Dot0) { bool isEntityOrFeed = (payloadKind == ODataPayloadKind.Entry) || (payloadKind == ODataPayloadKind.Feed); if (WebUtil.ResponseMediaTypeWouldBeJsonLight(host.RequestAccept, isEntityOrFeed)) { requestDescription.VerifyAndRaiseResponseVersion(RequestDescription.Version3Dot0, service); host.ResponseVersion = RequestDescription.Version3Dot0.ToString() + ";"; } } } if (this.requestDescription.TargetKind == RequestTargetKind.MediaResource) { this.mediaResourceStream = service.StreamProvider.GetReadStream(this.queryResults.Current, RequestDescription.GetStreamProperty(this.requestDescription), this.service.OperationContext); } else if (payloadKind != ODataPayloadKind.BinaryValue) { string requestAcceptCharSet = this.service.OperationContext.Host.RequestAcceptCharSet; if (string.IsNullOrEmpty(requestAcceptCharSet) || (requestAcceptCharSet == "*")) { requestAcceptCharSet = "UTF-8"; } if ((payloadKind == ODataPayloadKind.Value) && !string.IsNullOrEmpty(this.requestDescription.MimeType)) { this.messageWriter = CreateMessageWriter(this.AbsoluteServiceUri, this.service, this.requestDescription.ActualResponseVersion, responseMessage, ODataFormat.RawValue); } else { this.messageWriter = CreateMessageWriter(this.AbsoluteServiceUri, this.service, this.requestDescription.ActualResponseVersion, responseMessage, this.service.OperationContext.Host.RequestAccept, requestAcceptCharSet); } try { this.contentFormat = ODataUtils.SetHeadersForPayload(this.messageWriter, payloadKind); if ((payloadKind == ODataPayloadKind.Value) && !string.IsNullOrEmpty(this.requestDescription.MimeType)) { responseMessage.SetHeader("Content-Type", this.requestDescription.MimeType); } } catch (ODataContentTypeException exception) { throw new DataServiceException(0x19f, null, System.Data.Services.Strings.DataServiceException_UnsupportedMediaType, null, exception); } string headerValue = this.requestDescription.ResponseVersion.ToString() + ";"; responseMessage.SetHeader("DataServiceVersion", headerValue); } }
public void CopyConstructorShouldCopyAnnotationFilter() { ODataMessageReaderSettings testSubject = new ODataMessageReaderSettings(); testSubject.ShouldIncludeAnnotation = ODataUtils.CreateAnnotationFilter("namespace.*"); var copy = testSubject.Clone(); Assert.Same(testSubject.ShouldIncludeAnnotation, copy.ShouldIncludeAnnotation); }
public void VerifyResponseTest() { var response = this.CreateResponseMessage(); Assert.AreEqual(200, response.StatusCode); Assert.AreEqual("application/atom+xml;type=entry;charset=utf-8", response.GetHeader(ODataConstants.ContentTypeHeader)); Assert.AreEqual(ODataVersion.V1, ODataUtils.StringToODataVersion(response.GetHeader(ODataConstants.DataServiceVersionHeader))); response.GetStream().Dispose(); }
/// <inheritdoc/> public virtual async Task <HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken) { IHttpActionResult result = GetInnerActionResult(Request); HttpResponseMessage response = await result.ExecuteAsync(cancellationToken); response.Headers.Location = LocationHeader; ResultHelpers.AddEntityId(response, () => GenerateEntityId(Request)); ResultHelpers.AddServiceVersion(response, () => ODataUtils.ODataVersionToString(ResultHelpers.GetODataResponseVersion(Request))); return(response); }
private ODataMediaType GetAppendedMediaTypeObject(string mediaType) { var appendedMediaType = ODataUtils.AppendDefaultHeaderValue(ODataConstants.ContentTypeHeader, mediaType); var mediaTypeList = HttpUtils.MediaTypesFromString(appendedMediaType); Assert.True(mediaTypeList.Count == 1); return(mediaTypeList[0].Key); }
/// <inheritdoc/> public override void WriteResponseHeaders(OutputFormatterWriteContext context) { if (context == null) { throw Error.ArgumentNull("context"); } Type type = context.ObjectType; if (type == null) { throw Error.ArgumentNull("type"); } type = TypeHelper.GetTaskInnerTypeOrSelf(type); HttpRequest request = context.HttpContext.Request; if (request == null) { throw Error.InvalidOperation(SRResources.WriteToStreamAsyncMustHaveRequest); } HttpResponse response = context.HttpContext.Response; response.ContentType = context.ContentType.Value; MediaTypeHeaderValue contentType = GetContentType(response.Headers[HeaderNames.ContentType].FirstOrDefault()); // Determine the content type. MediaTypeHeaderValue newMediaType = null; if (ODataOutputFormatterHelper.TryGetContentHeader(type, contentType, out newMediaType)) { response.Headers[HeaderNames.ContentType] = new StringValues(newMediaType.ToString()); } // Set the character set. MediaTypeHeaderValue currentContentType = GetContentType(response.Headers[HeaderNames.ContentType].FirstOrDefault()); RequestHeaders requestHeader = request.GetTypedHeaders(); if (requestHeader != null && requestHeader.AcceptCharset != null) { IEnumerable <string> acceptCharsetValues = requestHeader.AcceptCharset.Select(cs => cs.Value.Value); string newCharSet = string.Empty; if (ODataOutputFormatterHelper.TryGetCharSet(currentContentType, acceptCharsetValues, out newCharSet)) { currentContentType.CharSet = newCharSet; response.Headers[HeaderNames.ContentType] = new StringValues(currentContentType.ToString()); } } // Add version header. response.Headers[ODataVersionConstraint.ODataServiceVersionHeader] = ODataUtils.ODataVersionToString(ResultHelpers.GetODataResponseVersion(request)); }
public void GetDataServiceVersionWorksForRequest() { InMemoryMessage simulatedRequestMessage = new InMemoryMessage(); simulatedRequestMessage.SetHeader(ODataConstants.ODataVersionHeader, "4.0"); IODataRequestMessage request = new ODataRequestMessage(simulatedRequestMessage, false, false, long.MaxValue); ODataVersion version = request.GetODataVersion(ODataVersion.V4); version.Should().Be(ODataUtils.StringToODataVersion(request.GetHeader(ODataConstants.ODataVersionHeader))); }
public void CharsetShouldNotBeIgnored_UTF8() { const string headerValue = MimeConstants.MimeApplicationJson + ";" + MimeConstants.MimeMetadataParameterName + "=" + MimeConstants.MimeMetadataParameterValueNone + ";" + MimeConstants.MimeIeee754CompatibleParameterName + "=" + MimeConstants.MimeParameterValueTrue + ";" + MimeConstants.MimeStreamingParameterName + "=" + MimeConstants.MimeParameterValueFalse + ";charset=utf-8"; var appendedHeaderValue = ODataUtils.AppendDefaultHeaderValue(ODataConstants.ContentTypeHeader, headerValue); Assert.True(appendedHeaderValue.Contains("charset=utf-8")); }
/// <summary> /// Verifies that the result of the test is what is expected. /// It does so by delegating to the inner expected result provided in the constructor and additionally checking the reported <see cref="ODataFormat"/>. /// </summary> /// <param name="messageReader">The message reader which is the result of the test. This method should use it to read the results /// of the parsing and verify those.</param> /// <param name="payloadKind">The payload kind specified in the test descriptor.</param> /// <param name="testConfiguration">The test configuration to use.</param> public override void VerifyResult(ODataMessageReaderTestWrapper messageReader, ODataPayloadKind payloadKind, ReaderTestConfiguration testConfiguration) { if (this.innerExpectedResult != null) { this.innerExpectedResult.VerifyResult(messageReader, payloadKind, testConfiguration); } ODataFormat actualFormat = ODataUtils.GetReadFormat(messageReader.MessageReader); this.settings.Assert.AreEqual(this.expectedFormat, actualFormat, "Formats don't match."); }
public void GetDataServiceVersionWorksForResponse() { InMemoryMessage simulatedRequestMessage = new InMemoryMessage(); simulatedRequestMessage.SetHeader(ODataConstants.ODataVersionHeader, "4.0"); IODataResponseMessage response = new ODataResponseMessage(simulatedRequestMessage, false, false, long.MaxValue); ODataVersion version = response.GetODataVersion(ODataVersion.V4); Assert.Equal(ODataUtils.StringToODataVersion(response.GetHeader(ODataConstants.ODataVersionHeader)), version); }
private static ODataVersion?GetODataVersion(string versionString) { try { return(ODataUtils.StringToODataVersion(versionString)); } catch (ODataException) { return(null); } }
public override async Task <HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken) { base.Request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); HttpResponseMessage response = await base.ExecuteAsync(cancellationToken); response.Headers.TryAddWithoutValidation( ODataServiceVersionHeader, ODataUtils.ODataVersionToString(ODataVersion.V4)); return(response); }
/// <inheritdoc/> public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType) { if (type == null) { throw Error.ArgumentNull("type"); } if (headers == null) { throw Error.ArgumentNull("headers"); } // When the user asks for application/json we really need to set the content type to // application/json; odata.metadata=minimal. If the user provides the media type and is // application/json we are going to add automatically odata.metadata=minimal. Otherwise we are // going to fallback to the default implementation. // When calling this formatter as part of content negotiation the content negotiator will always // pick a non null media type. In case the user creates a new ObjectContent<T> and doesn't pass in a // media type, we delegate to the base class to rely on the default behavior. It's the user's // responsibility to pass in the right media type. if (mediaType != null) { if (mediaType.MediaType.Equals("application/json", StringComparison.OrdinalIgnoreCase) && !mediaType.Parameters.Any(p => p.Name.Equals("odata.metadata", StringComparison.OrdinalIgnoreCase))) { mediaType.Parameters.Add(new NameValueHeaderValue("odata.metadata", "minimal")); } headers.ContentType = (MediaTypeHeaderValue)((ICloneable)mediaType).Clone(); } else { // This is the case when a user creates a new ObjectContent<T> passing in a null mediaType base.SetDefaultContentHeaders(type, headers, mediaType); } // In general, in Web API we pick a default charset based on the supported character sets // of the formatter. However, according to the OData spec, the service shouldn't be sending // a character set unless explicitly specified, so if the client didn't send the charset we chose // we just clean it. if (headers.ContentType != null && !Request.Headers.AcceptCharset .Any(cs => cs.Value.Equals(headers.ContentType.CharSet, StringComparison.OrdinalIgnoreCase))) { headers.ContentType.CharSet = String.Empty; } headers.TryAddWithoutValidation( HttpRequestMessageProperties.ODataServiceVersionHeader, ODataUtils.ODataVersionToString(_version)); }
private void WriteEntity(Stream stream, OeEntityItem entityItem) { IODataResponseMessage responseMessage = new OeInMemoryMessage(stream, null); using (ODataMessageWriter messageWriter = new ODataMessageWriter(responseMessage, _settings, _model)) { ODataUtils.SetHeadersForPayload(messageWriter, ODataPayloadKind.Resource); ODataWriter writer = messageWriter.CreateODataResourceWriter(entityItem.EntitySet, entityItem.EntityType); writer.WriteStart(entityItem.Entry); writer.WriteEnd(); } }