/// <inheritdoc/> public override bool CanWriteType(Type type) { if (type == null) { throw Error.ArgumentNull("type"); } if (Request != null) { ODataSerializerProvider serializerProvider = Request.GetRequestContainer() .GetRequiredService <ODataSerializerProvider>(); // See if this type is a SingleResult or is derived from SingleResult. bool isSingleResult = false; if (type.IsGenericType) { Type genericType = type.GetGenericTypeDefinition(); Type baseType = TypeHelper.GetBaseType(type); isSingleResult = (genericType == typeof(SingleResult <>) || baseType == typeof(SingleResult)); } return(ODataOutputFormatterHelper.CanWriteType( type, _payloadKinds, isSingleResult, new WebApiRequestMessage(Request), (objectType) => serializerProvider.GetODataPayloadSerializer(objectType, Request))); } return(false); }
/// <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(ResultHelpers.GetODataResponseVersion(Request))); }
/// <inheritdoc/> public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding) { 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; if (typeof(Stream).IsAssignableFrom(type)) { // Ideally, it should go into the "ODataRawValueSerializer", // However, OData lib doesn't provide the method to overwrite/copyto stream // So, Here's the workaround Stream objStream = context.Object as Stream; return(CopyStreamAsync(objStream, response)); } Uri baseAddress = GetBaseAddressInternal(request); MediaTypeHeaderValue contentType = GetContentType(response.Headers[HeaderNames.ContentType].FirstOrDefault()); Func <ODataSerializerContext> getODataSerializerContext = () => { return(new ODataSerializerContext() { Request = request, }); }; ODataSerializerProvider serializerProvider = request.GetRequestContainer().GetRequiredService <ODataSerializerProvider>(); return(ODataOutputFormatterHelper.WriteToStreamAsync( type, context.Object, request.GetModel(), ResultHelpers.GetODataResponseVersion(request), baseAddress, contentType, new WebApiUrlHelper(request.GetUrlHelper()), new WebApiRequestMessage(request), new WebApiRequestHeaders(request.Headers), (services) => ODataMessageWrapperHelper.Create(new StreamWrapper(response.Body), response.Headers, services), (edmType) => serializerProvider.GetEdmTypeSerializer(edmType), (objectType) => serializerProvider.GetODataPayloadSerializer(objectType, request), getODataSerializerContext)); }
/// <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 override Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding) { 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); } try { HttpResponse response = context.HttpContext.Response; Uri baseAddress = GetBaseAddressInternal(request); MediaTypeHeaderValue contentType = GetContentType(response.Headers[HeaderNames.ContentType].FirstOrDefault()); Func <ODataSerializerContext> getODataSerializerContext = () => { return(new ODataSerializerContext() { Request = request, }); }; ODataSerializerProvider serializerProvider = request.GetRequestContainer().GetRequiredService <ODataSerializerProvider>(); ODataOutputFormatterHelper.WriteToStream( type, context.Object, request.GetModel(), ResultHelpers.GetODataResponseVersion(request), baseAddress, contentType, new WebApiUrlHelper(request.GetUrlHelper()), new WebApiRequestMessage(request), new WebApiRequestHeaders(request.Headers), (services) => ODataMessageWrapperHelper.Create(response.Body, response.Headers, services), (edmType) => serializerProvider.GetEdmTypeSerializer(edmType), (objectType) => serializerProvider.GetODataPayloadSerializer(objectType, request), getODataSerializerContext); return(TaskHelpers.Completed()); } catch (Exception ex) { return(TaskHelpers.FromError(ex)); } }
/// <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(ResultHelpers.GetODataResponseVersion(Request))); // Add Preference-Applied headers var responseMessage = ODataOutputFormatterHelper.PrepareResponseMessage( new WebApiRequestMessage(Request), new WebApiRequestHeaders(Request.Headers), (services) => ODataMessageWrapperHelper.Create(null, headers, services)); foreach (var header in responseMessage.Headers) { if (!headers.Contains(header.Key)) { headers.TryAddWithoutValidation(header.Key, header.Value); } } }
/// <inheritdoc/> public override bool CanWriteResult(OutputFormatterCanWriteContext context) { if (context == null) { throw Error.ArgumentNull("context"); } // Ensure we have a valid request. HttpRequest request = context.HttpContext.Request; if (request == null) { throw Error.InvalidOperation(SRResources.ReadFromStreamAsyncMustHaveRequest); } // Ignore non-OData requests. if (request.ODataFeature().Path == null) { return(false); } // The following base.CanWriteResult(context) will change the context.ContentType // If this formatter can't write the result, we should reset the context.ContentType to its original value. // So that, the other formatter can make a descison based on the original content type. // Be noted: in .NET 5, the context.ContentType is a new StringSegment everytime when goes into each formatter // formatterContext.ContentType = new StringSegment(); // So, in .NET 5, we don't need to reset the contentType to backupContentType. StringSegment backupContentType = context.ContentType; // Allow the base class to make its determination, which includes // checks for SupportedMediaTypes. bool suportedMediaTypeFound = false; if (SupportedMediaTypes.Any()) { suportedMediaTypeFound = base.CanWriteResult(context); } // See if the request satisfies any mappings. IEnumerable <MediaTypeMapping> matchedMappings = (MediaTypeMappings == null) ? null : MediaTypeMappings .Where(m => (m.TryMatchMediaType(request) > 0)); // Now pick the best content type. If a media mapping was found, use that and override the // value specified by the controller, if any. Otherwise, let the base class decide. if (matchedMappings != null && matchedMappings.Any()) { context.ContentType = matchedMappings.First().MediaType.ToString(); } else if (!suportedMediaTypeFound) { context.ContentType = backupContentType; return(false); } // We need the type in order to write it. Type type = context.ObjectType ?? context.Object?.GetType(); if (type == null) { context.ContentType = backupContentType; return(false); } type = TypeHelper.GetTaskInnerTypeOrSelf(type); ODataSerializerProvider serializerProvider = request.GetRequestContainer().GetRequiredService <ODataSerializerProvider>(); // See if this type is a SingleResult or is derived from SingleResult. bool isSingleResult = false; if (type.IsGenericType) { Type genericType = type.GetGenericTypeDefinition(); Type baseType = TypeHelper.GetBaseType(type); isSingleResult = (genericType == typeof(SingleResult <>) || baseType == typeof(SingleResult)); } bool result = ODataOutputFormatterHelper.CanWriteType( type, _payloadKinds, isSingleResult, new WebApiRequestMessage(request), (objectType) => serializerProvider.GetODataPayloadSerializer(objectType, request)); if (!result) { context.ContentType = backupContentType; } return(result); }
public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken) { if (type == null) { throw Error.ArgumentNull("type"); } if (writeStream == null) { throw Error.ArgumentNull("writeStream"); } if (Request == null) { throw Error.InvalidOperation(SRResources.WriteToStreamAsyncMustHaveRequest); } if (cancellationToken.IsCancellationRequested) { return(TaskHelpers.Canceled()); } try { HttpConfiguration configuration = Request.GetConfiguration(); if (configuration == null) { throw Error.InvalidOperation(SRResources.RequestMustContainConfiguration); } HttpContentHeaders contentHeaders = (content == null) ? null : content.Headers; UrlHelper urlHelper = Request.GetUrlHelper() ?? new UrlHelper(Request); Func <ODataSerializerContext> getODataSerializerContext = () => { return(new ODataSerializerContext() { Request = Request, Url = urlHelper, }); }; ODataSerializerProvider serializerProvider = Request.GetRequestContainer() .GetRequiredService <ODataSerializerProvider>(); ODataOutputFormatterHelper.WriteToStream( type, value, Request.GetModel(), ResultHelpers.GetODataResponseVersion(Request), GetBaseAddressInternal(Request), contentHeaders == null ? null : contentHeaders.ContentType, new WebApiUrlHelper(urlHelper), new WebApiRequestMessage(Request), new WebApiRequestHeaders(Request.Headers), (services) => ODataMessageWrapperHelper.Create(writeStream, contentHeaders, services), (edmType) => serializerProvider.GetEdmTypeSerializer(edmType), (objectType) => serializerProvider.GetODataPayloadSerializer(objectType, Request), getODataSerializerContext); return(TaskHelpers.Completed()); } catch (Exception ex) { return(TaskHelpers.FromError(ex)); } }