public static ODataSerializerProvider GetMockODataSerializerProvider(ODataSerializer serializer) { Mock <ODataSerializerProvider> serializerProvider = new Mock <ODataSerializerProvider>(); serializerProvider.Setup(sp => sp.GetODataPayloadSerializer(It.IsAny <IEdmModel>(), It.IsAny <Type>())).Returns(serializer); return(serializerProvider.Object); }
public void GetODataSerializer_ReturnsNull_IfTypeUnknown() { // Arrange HttpRequest request = GetRequest(_edmModel); // Act ODataSerializer serializer = _serializerProvider.GetODataPayloadSerializer(typeof(UnknownEntityType), request); // Assert Assert.Null(serializer); }
/// <inheritdoc/> public override bool CanWriteType(Type type) { if (type == null) { throw Error.ArgumentNull("type"); } ODataSerializer serializer = ODataSerializerProvider.GetODataPayloadSerializer(type); return(serializer != null); }
private static ODataPayloadKind?GetClrObjectResponsePayloadKind(Type type, bool isGenericSingleResult, Func <Type, ODataSerializer> getODataPayloadSerializer) { // SingleResult<T> should be serialized as T. if (isGenericSingleResult) { type = type.GetGenericArguments()[0]; } ODataSerializer serializer = getODataPayloadSerializer(type); return(serializer == null ? null : (ODataPayloadKind?)serializer.ODataPayloadKind); }
private ODataPayloadKind?GetClrObjectResponsePayloadKind(Type type, IEdmModel model) { // SingleResult<T> should be serialized as T. if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(SingleResult <>)) { type = type.GetGenericArguments()[0]; } ODataSerializer serializer = _serializerProvider.GetODataPayloadSerializer(model, type, Request); return(serializer == null ? null : (ODataPayloadKind?)serializer.ODataPayloadKind); }
public void GetODataSerializer_Returns_ExpectedSerializerType(Type payloadType, Type expectedSerializerType) { // Arrange var request = RequestFactory.Create(); // Act ODataSerializer serializer = _serializerProvider.GetODataPayloadSerializer(payloadType, request); // Assert Assert.NotNull(serializer); Assert.IsType(expectedSerializerType, serializer); }
public void GetODataSerializer_ReturnsSameSerializer_ForSameType() { // Arrange HttpRequest request = GetRequest(_edmModel); // Act ODataSerializer firstCallSerializer = _serializerProvider.GetODataPayloadSerializer(typeof(Product), request); ODataSerializer secondCallSerializer = _serializerProvider.GetODataPayloadSerializer(typeof(Product), request); // Assert Assert.Same(firstCallSerializer, secondCallSerializer); }
public void GetEdmTypeSerializer_Caches_CreateEdmTypeSerializerOutput() { // Arrange IEdmTypeReference edmType = new Mock <IEdmTypeReference>().Object; // Act ODataSerializer serializer1 = _serializerProvider.GetEdmTypeSerializer(edmType); ODataSerializer serializer2 = _serializerProvider.GetEdmTypeSerializer(edmType); // Assert Assert.Same(serializer2, serializer1); }
public void GetODataSerializer_Returns_ExpectedSerializerType(Type payloadType, Type expectedSerializerType) { // Arrange HttpRequest request = GetRequest(EdmCoreModel.Instance); // Act ODataSerializer serializer = _serializerProvider.GetODataPayloadSerializer(payloadType, request); // Assert Assert.NotNull(serializer); Assert.IsType(expectedSerializerType, serializer); }
public void GetODataSerializer_ReturnsSameSerializer_ForSameType() { // Arrange var request = RequestFactory.CreateFromModel(_edmModel); // Act ODataSerializer firstCallSerializer = _serializerProvider.GetODataPayloadSerializer( typeof(ODataResourceDeserializerTests.Supplier), request); ODataSerializer secondCallSerializer = _serializerProvider.GetODataPayloadSerializer( typeof(ODataResourceDeserializerTests.Supplier), request); // Assert Assert.Same(firstCallSerializer, secondCallSerializer); }
public void GetODataSerializer_Enum() { // Arrange HttpRequest request = GetRequest(_edmModel); // Act ODataSerializer serializer = _serializerProvider.GetODataPayloadSerializer(typeof(TestEnum), request); // Assert Assert.NotNull(serializer); var enumSerializer = Assert.IsType <ODataEnumSerializer>(serializer); Assert.Equal(ODataPayloadKind.Property, enumSerializer.ODataPayloadKind); }
public void GetODataSerializer_Primitive(Type type, EdmPrimitiveTypeKind edmPrimitiveTypeKind) { // Arrange HttpRequest request = GetRequest(EdmCoreModel.Instance); // Act ODataSerializer serializer = _serializerProvider.GetODataPayloadSerializer(type, request); // Assert Assert.NotEqual(EdmPrimitiveTypeKind.None, edmPrimitiveTypeKind); Assert.NotNull(serializer); ODataPrimitiveSerializer primitiveSerializer = Assert.IsType <ODataPrimitiveSerializer>(serializer); Assert.Equal(ODataPayloadKind.Property, primitiveSerializer.ODataPayloadKind); }
public void GetODataSerializer_ResourceSet_ForComplexCollection(Type collectionType) { // Arrange HttpRequest request = GetRequest(_edmModel); // Act ODataSerializer serializer = _serializerProvider.GetODataPayloadSerializer(collectionType, request); // Assert Assert.NotNull(serializer); var resourceSetSerializer = Assert.IsType <ODataResourceSetSerializer>(serializer); Assert.Equal(ODataPayloadKind.ResourceSet, resourceSetSerializer.ODataPayloadKind); Assert.Same(resourceSetSerializer.SerializerProvider, _serializerProvider); }
public void GetODataSerializer_Resource_ForComplex() { // Arrange HttpRequest request = GetRequest(_edmModel); // Act ODataSerializer serializer = _serializerProvider.GetODataPayloadSerializer(typeof(Address), request); // Assert Assert.NotNull(serializer); var complexSerializer = Assert.IsType <ODataResourceSerializer>(serializer); Assert.Equal(complexSerializer.SerializerProvider, _serializerProvider); Assert.Equal(ODataPayloadKind.Resource, complexSerializer.ODataPayloadKind); }
public void GetODataSerializer_Resource_ForEntity() { // Arrange HttpRequest request = GetRequest(_edmModel); // Act ODataSerializer serializer = _serializerProvider.GetODataPayloadSerializer(typeof(Product), request); // Assert Assert.NotNull(serializer); var entitySerializer = Assert.IsType <ODataResourceSerializer>(serializer); Assert.Equal(entitySerializer.SerializerProvider, _serializerProvider); Assert.Equal(ODataPayloadKind.Resource, entitySerializer.ODataPayloadKind); }
private ODataPayloadKind?GetClrObjectResponsePayloadKind(Type type, OutputFormatterWriteContext context) { // SingleResult<T> should be serialized as T. //if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(SingleResult<>)) //{ // type = type.GetGenericArguments()[0]; //} IODataSerializerProvider provider = context.HttpContext.RequestServices.GetRequiredService <IODataSerializerProvider>(); ODataSerializer serializer = provider.GetODataPayloadSerializer(context.HttpContext, type); return(serializer == null ? null : (ODataPayloadKind?)serializer.ODataPayloadKind); }
/// <inheritdoc/> public override bool CanWriteType(Type type) { if (type == null) { throw Error.ArgumentNull("type"); } ODataSerializer serializer = _serializerProvider.GetODataPayloadSerializer(type); if (serializer == null) { return(false); } return(_payloadKinds.Contains(serializer.ODataPayloadKind)); }
public void GetODataPayloadSerializer_ReturnsRawValueSerializer_ForValueRequests(Type type, EdmPrimitiveTypeKind edmPrimitiveTypeKind) { // Arrange ODataPath odataPath = new ODataPath(new ValueSegment(EdmCoreModel.Instance.GetPrimitiveType(EdmPrimitiveTypeKind.Int32))); HttpRequest request = GetRequest(EdmCoreModel.Instance); request.ODataFeature().Path = odataPath; // Act ODataSerializer serializer = _serializerProvider.GetODataPayloadSerializer(type, request); // Assert Assert.NotEqual(EdmPrimitiveTypeKind.None, edmPrimitiveTypeKind); Assert.NotNull(serializer); Assert.Equal(ODataPayloadKind.Value, serializer.ODataPayloadKind); }
public void GetODataPayloadSerializer_ReturnsRawValueSerializer_ForEnumValueRequests() { // Arrange ODataPath odataPath = new ODataPath(new ValueSegment(EdmCoreModel.Instance.GetPrimitiveType(EdmPrimitiveTypeKind.Int32))); HttpRequest request = GetRequest(_edmModel); request.ODataFeature().Path = odataPath; // Act ODataSerializer serializer = _serializerProvider.GetODataPayloadSerializer(typeof(TestEnum), request); // Assert Assert.NotNull(serializer); var rawValueSerializer = Assert.IsType <ODataRawValueSerializer>(serializer); Assert.Equal(ODataPayloadKind.Value, rawValueSerializer.ODataPayloadKind); }
/// <summary> /// Gets the serializer for the given result type. /// </summary> /// <param name="type">The type of result to serialize.</param> /// <param name="request">The HTTP request.</param> /// <returns>The serializer instance.</returns> public override ODataSerializer GetODataPayloadSerializer( Type type, HttpRequestMessage request) { ODataSerializer serializer = null; if (type.Name == "PrimitiveResult") { serializer = this.primitiveSerializer; } else { serializer = base.GetODataPayloadSerializer(type, request); } return(serializer); }
/// <summary> /// Gets the serializer for the given result type. /// </summary> /// <param name="model">The EDM model.</param> /// <param name="type">The type of result to serialize.</param> /// <param name="request">The HTTP request.</param> /// <returns>The serializer instance.</returns> public override ODataSerializer GetODataPayloadSerializer( IEdmModel model, Type type, HttpRequestMessage request) { ODataSerializer serializer = base.GetODataPayloadSerializer(model, type, request); if (serializer == null) { if (type == typeof(EntityCollectionResult)) { serializer = this.feedSerializer; } else if (type == typeof(EntityResult)) { serializer = this.entityTypeSerializer; } else if (type == typeof(PrimitiveResult)) { serializer = this.primitiveSerializer; } else if (type == typeof(RawResult)) { serializer = this.rawSerializer; } else if (type == typeof(ComplexResult)) { serializer = this.complexTypeSerializer; } else if (type == typeof(NonEntityCollectionResult)) { serializer = this.collectionSerializer; } else if (type == typeof(EnumResult)) { serializer = this.enumSerializer; } } return(serializer); }
/// <summary> /// Gets the serializer for the given result type. /// </summary> /// <param name="model">The EDM model.</param> /// <param name="type">The type of result to serialize.</param> /// <param name="request">The HTTP request.</param> /// <returns>The serializer instance.</returns> public override ODataSerializer GetODataPayloadSerializer( IEdmModel model, Type type, HttpRequestMessage request) { ODataSerializer serializer = base.GetODataPayloadSerializer(model, type, request); if (serializer == null) { if (type == typeof(EntityCollectionResult)) { serializer = this.feedSerializer; } else if (type == typeof(EntityResult)) { serializer = this.entityTypeSerializer; } } return(serializer); }
/// <inheritdoc/> public override bool CanWriteType(Type type) { if (type == null) { throw Error.ArgumentNull("type"); } if (_request != null) { IEdmModel model = _request.GetEdmModel(); if (model != null) { ODataSerializer serializer = _serializerProvider.GetODataPayloadSerializer(model, type); if (serializer != null) { return(_payloadKinds.Contains(serializer.ODataPayloadKind)); } } } return(false); }
private IEnumerable <KeyValuePair <string, string> > GetResponseMessageHeaders(Type graphType, ODataFormat odataFormat, ODataVersion version) { IODataResponseMessage responseMessage = new ODataMessageWrapper(); ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings() { BaseUri = new Uri(ODataFormatterConstants.DefaultNamespace), Version = version, Indent = false }; writerSettings.SetContentType(odataFormat); using (ODataMessageWriter messageWriter = new ODataMessageWriter(responseMessage, writerSettings)) { ODataSerializer serializer = ODataSerializerProvider.GetODataPayloadSerializer(graphType); // get the OData specific headers for the payloadkind ODataUtils.SetHeadersForPayload(messageWriter, serializer.ODataPayloadKind); } return(responseMessage.Headers); }
/// <summary> /// Gets the serializer for the given result type. /// </summary> /// <param name="type">The type of result to serialize.</param> /// <param name="request">The HTTP request.</param> /// <returns>The serializer instance.</returns> public override ODataSerializer GetODataPayloadSerializer( Type type, HttpRequestMessage request) { ODataSerializer serializer = null; if (type == typeof(ResourceSetResult)) { serializer = this.resourceSetSerializer; } else if (type == typeof(PrimitiveResult)) { serializer = this.primitiveSerializer; } else if (type == typeof(RawResult)) { serializer = this.rawSerializer; } else if (type == typeof(ComplexResult)) { serializer = this.resourceSerializer; } else if (type == typeof(NonResourceCollectionResult)) { serializer = this.collectionSerializer; } else if (type == typeof(EnumResult)) { serializer = this.enumSerializer; } else { serializer = base.GetODataPayloadSerializer(type, request); } return(serializer); }
private void WriteToStream(Type type, object value, Stream writeStream, HttpContent content, HttpContentHeaders contentHeaders) { IEdmModel model = Request.ODataProperties().Model; if (model == null) { throw Error.InvalidOperation(SRResources.RequestMustHaveModel); } ODataSerializer serializer = GetSerializer(type, value, model, _serializerProvider); UrlHelper urlHelper = Request.GetUrlHelper() ?? new UrlHelper(Request); ODataPath path = Request.ODataProperties().Path; IEdmNavigationSource targetNavigationSource = path == null ? null : path.NavigationSource; // serialize a response HttpConfiguration configuration = Request.GetConfiguration(); if (configuration == null) { throw Error.InvalidOperation(SRResources.RequestMustContainConfiguration); } string preferHeader = RequestPreferenceHelpers.GetRequestPreferHeader(Request); string annotationFilter = null; if (!String.IsNullOrEmpty(preferHeader)) { ODataMessageWrapper messageWrapper = new ODataMessageWrapper(writeStream, content.Headers); messageWrapper.SetHeader(RequestPreferenceHelpers.PreferHeaderName, preferHeader); annotationFilter = messageWrapper.PreferHeader().AnnotationFilter; } IODataResponseMessage responseMessage = new ODataMessageWrapper(writeStream, content.Headers); if (annotationFilter != null) { responseMessage.PreferenceAppliedHeader().AnnotationFilter = annotationFilter; } Uri baseAddress = GetBaseAddress(Request); ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings(MessageWriterSettings) { PayloadBaseUri = baseAddress, Version = _version, }; string metadataLink = urlHelper.CreateODataLink(new MetadataPathSegment()); if (metadataLink == null) { throw new SerializationException(SRResources.UnableToDetermineMetadataUrl); } writerSettings.ODataUri = new ODataUri { ServiceRoot = baseAddress, // TODO: 1604 Convert webapi.odata's ODataPath to ODL's ODataPath, or use ODL's ODataPath. SelectAndExpand = Request.ODataProperties().SelectExpandClause, Path = (path == null || IsOperationPath(path)) ? null : path.ODLPath, }; MediaTypeHeaderValue contentType = null; if (contentHeaders != null && contentHeaders.ContentType != null) { contentType = contentHeaders.ContentType; } using (ODataMessageWriter messageWriter = new ODataMessageWriter(responseMessage, writerSettings, model)) { ODataSerializerContext writeContext = new ODataSerializerContext() { Request = Request, RequestContext = Request.GetRequestContext(), Url = urlHelper, NavigationSource = targetNavigationSource, Model = model, RootElementName = GetRootElementName(path) ?? "root", SkipExpensiveAvailabilityChecks = serializer.ODataPayloadKind == ODataPayloadKind.Feed, Path = path, MetadataLevel = ODataMediaTypes.GetMetadataLevel(contentType), SelectExpandClause = Request.ODataProperties().SelectExpandClause }; serializer.WriteObject(value, type, messageWriter, writeContext); } }
internal static void WriteToStream( Type type, object value, IEdmModel model, ODataVersion version, Uri baseAddress, MediaTypeHeaderValue contentType, IWebApiUrlHelper internaUrlHelper, IWebApiRequestMessage internalRequest, IWebApiHeaders internalRequestHeaders, Func <IServiceProvider, ODataMessageWrapper> getODataMessageWrapper, Func <IEdmTypeReference, ODataSerializer> getEdmTypeSerializer, Func <Type, ODataSerializer> getODataPayloadSerializer, Func <ODataSerializerContext> getODataSerializerContext) { if (model == null) { throw Error.InvalidOperation(SRResources.RequestMustHaveModel); } ODataSerializer serializer = GetSerializer(type, value, internalRequest, getEdmTypeSerializer, getODataPayloadSerializer); ODataPath path = internalRequest.Context.Path; IEdmNavigationSource targetNavigationSource = path == null ? null : path.NavigationSource; // serialize a response string preferHeader = RequestPreferenceHelpers.GetRequestPreferHeader(internalRequestHeaders); string annotationFilter = null; if (!String.IsNullOrEmpty(preferHeader)) { ODataMessageWrapper messageWrapper = getODataMessageWrapper(null); messageWrapper.SetHeader(RequestPreferenceHelpers.PreferHeaderName, preferHeader); annotationFilter = messageWrapper.PreferHeader().AnnotationFilter; } IODataResponseMessage responseMessage = getODataMessageWrapper(internalRequest.RequestContainer); if (annotationFilter != null) { responseMessage.PreferenceAppliedHeader().AnnotationFilter = annotationFilter; } ODataMessageWriterSettings writerSettings = internalRequest.WriterSettings; writerSettings.BaseUri = baseAddress; writerSettings.Version = version; writerSettings.Validations = writerSettings.Validations & ~ValidationKinds.ThrowOnUndeclaredPropertyForNonOpenType; string metadataLink = internaUrlHelper.CreateODataLink(MetadataSegment.Instance); if (metadataLink == null) { throw new SerializationException(SRResources.UnableToDetermineMetadataUrl); } //Set this variable if the SelectExpandClause is different from the processed clause on the Query options SelectExpandClause selectExpandDifferentFromQueryOptions = null; if (internalRequest.Context.QueryOptions != null && internalRequest.Context.QueryOptions.SelectExpand != null) { if (internalRequest.Context.QueryOptions.SelectExpand.ProcessedSelectExpandClause != internalRequest.Context.ProcessedSelectExpandClause) { selectExpandDifferentFromQueryOptions = internalRequest.Context.ProcessedSelectExpandClause; } } else if (internalRequest.Context.ProcessedSelectExpandClause != null) { selectExpandDifferentFromQueryOptions = internalRequest.Context.ProcessedSelectExpandClause; } writerSettings.ODataUri = new ODataUri { ServiceRoot = baseAddress, SelectAndExpand = internalRequest.Context.ProcessedSelectExpandClause, Apply = internalRequest.Context.ApplyClause, Path = ConvertPath(path), }; ODataMetadataLevel metadataLevel = ODataMetadataLevel.MinimalMetadata; if (contentType != null) { IEnumerable <KeyValuePair <string, string> > parameters = contentType.Parameters.Select(val => new KeyValuePair <string, string>(val.Name, val.Value)); metadataLevel = ODataMediaTypes.GetMetadataLevel(contentType.MediaType, parameters); } using (ODataMessageWriter messageWriter = new ODataMessageWriter(responseMessage, writerSettings, model)) { ODataSerializerContext writeContext = getODataSerializerContext(); writeContext.NavigationSource = targetNavigationSource; writeContext.Model = model; writeContext.RootElementName = GetRootElementName(path) ?? "root"; writeContext.SkipExpensiveAvailabilityChecks = serializer.ODataPayloadKind == ODataPayloadKind.ResourceSet; writeContext.Path = path; writeContext.MetadataLevel = metadataLevel; writeContext.QueryOptions = internalRequest.Context.QueryOptions; //Set the SelectExpandClause on the context if it was explicitly specified. if (selectExpandDifferentFromQueryOptions != null) { writeContext.SelectExpandClause = selectExpandDifferentFromQueryOptions; } serializer.WriteObject(value, type, messageWriter, writeContext); } }
public static ODataSerializerProvider GetMockODataSerializerProvider(ODataSerializer serializer) { Mock<ODataSerializerProvider> serializerProvider = new Mock<ODataSerializerProvider>(); serializerProvider.Setup(sp => sp.GetODataPayloadSerializer(It.IsAny<IEdmModel>(), It.IsAny<Type>(), It.IsAny<HttpRequestMessage>())) .Returns(serializer); return serializerProvider.Object; }
private void WriteResponseBody(OutputFormatterWriteContext context) { HttpRequest request = context.HttpContext.Request; HttpResponse response = context.HttpContext.Response; IEdmModel model = request.ODataProperties().Model; if (model == null) { throw Error.InvalidOperation(SRResources.RequestMustHaveModel); } object value = context.Object; Type type = value.GetType(); ODataSerializer serializer = GetSerializer(type, value, model, new DefaultODataSerializerProvider(), request); IUrlHelper urlHelper = context.HttpContext.UrlHelper(); ODataPath path = request.ODataProperties().Path; IEdmNavigationSource targetNavigationSource = path == null ? null : path.NavigationSource; string preferHeader = RequestPreferenceHelpers.GetRequestPreferHeader(request); string annotationFilter = null; if (!String.IsNullOrEmpty(preferHeader)) { ODataMessageWrapper messageWrapper = new ODataMessageWrapper(response.Body, response.Headers); messageWrapper.SetHeader(RequestPreferenceHelpers.PreferHeaderName, preferHeader); annotationFilter = messageWrapper.PreferHeader().AnnotationFilter; } IODataResponseMessage responseMessage = new ODataMessageWrapper(response.Body, response.Headers); if (annotationFilter != null) { responseMessage.PreferenceAppliedHeader().AnnotationFilter = annotationFilter; } Uri baseAddress = GetBaseAddress(request); ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings(_messageWriterSettings) { PayloadBaseUri = baseAddress, Version = ODataProperties.DefaultODataVersion, }; string metadataLink = urlHelper.CreateODataLink(new MetadataPathSegment()); if (metadataLink == null) { throw new SerializationException(SRResources.UnableToDetermineMetadataUrl); } writerSettings.ODataUri = new ODataUri { ServiceRoot = baseAddress, // TODO: 1604 Convert webapi.odata's ODataPath to ODL's ODataPath, or use ODL's ODataPath. SelectAndExpand = request.ODataProperties().SelectExpandClause, Path = (path == null || IsOperationPath(path)) ? null : path.ODLPath, }; using (ODataMessageWriter messageWriter = new ODataMessageWriter(responseMessage, writerSettings, model)) { ODataSerializerContext writeContext = new ODataSerializerContext() { Request = request, RequestContext = request.HttpContext, Url = urlHelper, NavigationSource = targetNavigationSource, Model = model, RootElementName = GetRootElementName(path) ?? "root", SkipExpensiveAvailabilityChecks = serializer.ODataPayloadKind == ODataPayloadKind.Feed, Path = path, MetadataLevel = ODataMediaTypes.GetMetadataLevel(new MediaTypeHeaderValue(context.ContentType.Value)), SelectExpandClause = request.ODataProperties().SelectExpandClause }; serializer.WriteObject(value, type, messageWriter, writeContext); } }
/// <summary> /// Read and serialize outgoing object to HTTP request stream. /// </summary> internal static void WriteToStream( Type type, object value, IEdmModel model, Uri baseAddress, MediaTypeHeaderValue contentType, IUrlHelper internalUrlHelper, HttpRequest internalRequest, IHeaderDictionary internalRequestHeaders, Func <IServiceProvider, ODataMigrationMessageWrapper> getODataMessageWrapper, Func <IEdmTypeReference, ODataSerializer> getEdmTypeSerializer, Func <Type, ODataSerializer> getODataPayloadSerializer, Func <ODataSerializerContext> getODataSerializerContext) { if (model == null) { throw new InvalidOperationException("Request must have model"); } ODataSerializer serializer = GetSerializer(type, value, internalRequest, getEdmTypeSerializer, getODataPayloadSerializer); // special case: if the top level serializer is an ODataPrimitiveSerializer then swap it out for an ODataMigrationPrimitiveSerializer // This only applies to the top level because inline primitives are translated but top level primitives are not, unless we use a customized serializer. if (serializer is ODataPrimitiveSerializer) { serializer = new ODataMigrationPrimitiveSerializer(); } ODataPath path = internalRequest.ODataFeature().Path; IEdmNavigationSource targetNavigationSource = path == null ? null : path.NavigationSource; // serialize a response string preferHeader = GetRequestPreferHeader(internalRequestHeaders); string annotationFilter = null; if (!String.IsNullOrEmpty(preferHeader)) { ODataMigrationMessageWrapper messageWrapper = getODataMessageWrapper(null); messageWrapper.SetHeader("Prefer", preferHeader); annotationFilter = messageWrapper.PreferHeader().AnnotationFilter; } ODataMigrationMessageWrapper responseMessageWrapper = getODataMessageWrapper(internalRequest.GetRequestContainer()); IODataResponseMessage responseMessage = responseMessageWrapper; if (annotationFilter != null) { responseMessage.PreferenceAppliedHeader().AnnotationFilter = annotationFilter; } ODataMessageWriterSettings writerSettings = internalRequest.GetWriterSettings(); writerSettings.BaseUri = baseAddress; writerSettings.Version = ODataVersion.V4; // Todo how to specify v3? Maybe don't because reading as v4 writerSettings.Validations = writerSettings.Validations & ~ValidationKinds.ThrowOnUndeclaredPropertyForNonOpenType; string metadataLink = internalUrlHelper.CreateODataLink(MetadataSegment.Instance); if (metadataLink == null) { throw new SerializationException("Unable to determine metadata url"); } writerSettings.ODataUri = new ODataUri { ServiceRoot = baseAddress, SelectAndExpand = internalRequest.ODataFeature()?.SelectExpandClause, Apply = internalRequest.ODataFeature().ApplyClause, Path = (path == null || IsOperationPath(path)) ? null : path.Path, }; ODataMetadataLevel metadataLevel = ODataMetadataLevel.MinimalMetadata; if (contentType != null) { IEnumerable <KeyValuePair <string, string> > parameters = contentType.Parameters.Select(val => new KeyValuePair <string, string>(val.Name.Value, val.Value.Value)); metadataLevel = ODataMediaTypes.GetMetadataLevel(contentType.MediaType.Value, parameters); } using (ODataMessageWriter messageWriter = new ODataMessageWriter(responseMessage, writerSettings, model)) { ODataSerializerContext writeContext = getODataSerializerContext(); writeContext.NavigationSource = targetNavigationSource; writeContext.Model = model; writeContext.RootElementName = GetRootElementName(path) ?? "root"; writeContext.SkipExpensiveAvailabilityChecks = serializer.ODataPayloadKind == ODataPayloadKind.ResourceSet; writeContext.Path = path; writeContext.SelectExpandClause = internalRequest.ODataFeature()?.SelectExpandClause; writeContext.MetadataLevel = metadataLevel; // Substitute stream to swap @odata.context Stream substituteStream = new MemoryStream(); Stream originalStream = messageWriter.SubstituteResponseStream(substituteStream); serializer.WriteObject(value, type, messageWriter, writeContext); StreamReader reader = new StreamReader(substituteStream); substituteStream.Seek(0, SeekOrigin.Begin); JToken responsePayload = JToken.Parse(reader.ReadToEnd()); // If odata context is present, replace with odata metadata if (responsePayload["@odata.context"] != null) { responsePayload["odata.metadata"] = responsePayload["@odata.context"].ToString().Replace("$entity", "@Element"); ((JObject)responsePayload).Property("@odata.context").Remove(); } // Write to actual stream // We cannot dispose of the stream because this method does not own the stream (subsequent methods will close the streamwriter) StreamWriter streamWriter = new StreamWriter(originalStream); JsonTextWriter writer = new JsonTextWriter(streamWriter); JsonSerializer jsonSerializer = new JsonSerializer(); jsonSerializer.Serialize(writer, responsePayload); writer.Flush(); messageWriter.SubstituteResponseStream(originalStream); } }
public async Task WriteJson(object value, Stream writeStream) { IEdmModel model = _odataProperties.Model; if (model == null) { throw new Exception("Microsoft.OData.Edm.Error.InvalidOperation(SRResources.RequestMustHaveModel)"); } var type = value.GetType(); type = _context.ObjectType; var pageResult = value as PageResult <object>; if (pageResult != null) { //value = pageResult.Items; type = pageResult.Items.GetType(); } var urlHelper = UrlHelper(_context.HttpContext); var path = Request.ODataFeature().Path; IEdmNavigationSource targetNavigationSource = path?.NavigationSource; // serialize a response //HttpConfiguration configuration = Request.GetConfiguration(); //if (configuration == null) //{ // throw Error.InvalidOperation(SRResources.RequestMustContainConfiguration); //} // TODO: Fix this ffs... string preferHeader = RequestPreferenceHelpers.GetRequestPreferHeader(Request); string annotationFilter = null; if (ODataCountMediaTypeMapping.IsCountRequest(Request.HttpContext)) { Response.ContentType = "text/plain"; } if (!String.IsNullOrEmpty(preferHeader)) { ODataMessageWrapper messageWrapper = new ODataMessageWrapper(writeStream, Response.Headers); messageWrapper.SetHeader(RequestPreferenceHelpers.PreferHeaderName, preferHeader); annotationFilter = messageWrapper.PreferHeader().AnnotationFilter; } IODataResponseMessage responseMessage = new ODataMessageWrapper(writeStream, Response.Headers); if (annotationFilter != null) { responseMessage.PreferenceAppliedHeader().AnnotationFilter = annotationFilter; } Uri baseAddress = GetBaseAddress(); ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings() { BaseUri = baseAddress, Version = _version, //MessageWriterSettings }; writerSettings.ODataUri = new ODataUri { ServiceRoot = baseAddress, // TODO: 1604 Convert webapi.odata's ODataPath to ODL's ODataPath, or use ODL's ODataPath. SelectAndExpand = Request.ODataFeature().SelectExpandClause, // TODO: Support $apply //Apply = Request.ODataFeature().ApplyClause, Path = (path == null || IsOperationPath(path)) ? null : path.ODLPath, }; MediaTypeHeaderValue contentType = null; // TODO: Restore //if (contentHeaders != null && contentHeaders.ContentType != null) //{ // contentType = contentHeaders.ContentType; //} using (ODataMessageWriter messageWriter = new ODataMessageWriter(responseMessage, writerSettings, model)) { ODataSerializer serializer = GetSerializer(type, value, model, _context.HttpContext.RequestServices.GetService <IODataSerializerProvider>()); ODataSerializerContext writeContext = new ODataSerializerContext() { Context = _context.HttpContext, Url = urlHelper, NavigationSource = targetNavigationSource, Model = model, RootElementName = GetRootElementName(path) ?? "root", SkipExpensiveAvailabilityChecks = serializer.ODataPayloadKind == ODataPayloadKind.Collection, Path = path, MetadataLevel = ODataMediaTypes.GetMetadataLevel(contentType), SelectExpandClause = Request.ODataFeature().SelectExpandClause }; await serializer.WriteObjectAsync(value, type, messageWriter, writeContext); } }