public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
        {
            if (type == null)
            {
                throw Error.ArgumentNull("type");
            }

            if (writeStream == null)
            {
                throw Error.ArgumentNull("writeStream");
            }

            if (_request == null)
            {
                throw Error.InvalidOperation(SRResources.WriteToStreamAsyncMustHaveRequest);
            }

            HttpContentHeaders contentHeaders = content == null ? null : content.Headers;

            return(TaskHelpers.RunSynchronously(() =>
            {
                // get the most appropriate serializer given that we support inheritance.
                IEdmModel model = _request.GetEdmModel();
                if (model == null)
                {
                    throw Error.InvalidOperation(SRResources.RequestMustHaveModel);
                }

                type = value == null ? type : value.GetType();
                ODataSerializer serializer = _serializerProvider.GetODataPayloadSerializer(model, type);
                if (serializer == null)
                {
                    string message = Error.Format(SRResources.TypeCannotBeSerialized, type.Name, typeof(ODataMediaTypeFormatter).Name);
                    throw new SerializationException(message);
                }

                UrlHelper urlHelper = _request.GetUrlHelper();
                Contract.Assert(urlHelper != null);

                ODataPath path = _request.GetODataPath();
                IEdmEntitySet targetEntitySet = path == null ? null : path.EntitySet;

                // serialize a response
                HttpConfiguration configuration = _request.GetConfiguration();
                if (configuration == null)
                {
                    throw Error.InvalidOperation(SRResources.RequestMustContainConfiguration);
                }

                IODataResponseMessage responseMessage = new ODataMessageWrapper(writeStream, content.Headers);

                ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings()
                {
                    BaseUri = GetBaseAddress(_request),
                    Version = _version,
                    Indent = true,
                    DisableMessageStreamDisposal = true,
                    MessageQuotas = MessageWriterQuotas
                };

                // The MetadataDocumentUri is never required for errors. Additionally, it sometimes won't be available
                // for errors, such as when routing itself fails. In that case, the route data property is not
                // available on the request, and due to a bug with HttpRoute.GetVirtualPath (bug #669) we won't be able
                // to generate a metadata link.
                if (serializer.ODataPayloadKind != ODataPayloadKind.Error)
                {
                    string metadataLink = urlHelper.ODataLink(new MetadataPathSegment());

                    if (metadataLink == null)
                    {
                        throw new SerializationException(SRResources.UnableToDetermineMetadataUrl);
                    }

                    writerSettings.SetMetadataDocumentUri(new Uri(metadataLink));
                }

                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,
                        Url = urlHelper,
                        EntitySet = targetEntitySet,
                        Model = model,
                        RootElementName = GetRootElementName(path) ?? "root",
                        SkipExpensiveAvailabilityChecks = serializer.ODataPayloadKind == ODataPayloadKind.Feed,
                        Path = path,
                        MetadataLevel = ODataMediaTypes.GetMetadataLevel(contentType),
                    };

                    serializer.WriteObject(value, messageWriter, writeContext);
                }
            }));
        }
        private void WriteToStream(Type type, object value, Stream writeStream, HttpContent content, HttpContentHeaders contentHeaders)
        {
            IEdmModel model = Request.GetEdmModel();

            if (model == null)
            {
                throw Error.InvalidOperation(SRResources.RequestMustHaveModel);
            }

            ODataSerializer serializer = GetSerializer(type, value, model, _serializerProvider);

            UrlHelper urlHelper = Request.GetUrlHelper();

            Contract.Assert(urlHelper != null);

            ODataPath     path            = Request.GetODataPath();
            IEdmEntitySet targetEntitySet = path == null ? null : path.EntitySet;

            // serialize a response
            HttpConfiguration configuration = Request.GetConfiguration();

            if (configuration == null)
            {
                throw Error.InvalidOperation(SRResources.RequestMustContainConfiguration);
            }

            IODataResponseMessage responseMessage = new ODataMessageWrapper(writeStream, content.Headers);

            ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings(MessageWriterSettings)
            {
                BaseUri = GetBaseAddress(Request),
                Version = _version,
            };

            // The MetadataDocumentUri is never required for errors. Additionally, it sometimes won't be available
            // for errors, such as when routing itself fails. In that case, the route data property is not
            // available on the request, and due to a bug with HttpRoute.GetVirtualPath (bug #669) we won't be able
            // to generate a metadata link.
            if (serializer.ODataPayloadKind != ODataPayloadKind.Error)
            {
                string metadataLink = urlHelper.ODataLink(new MetadataPathSegment());

                if (metadataLink == null)
                {
                    throw new SerializationException(SRResources.UnableToDetermineMetadataUrl);
                }

                string selectClause = GetSelectClause(Request);
                writerSettings.SetMetadataDocumentUri(new Uri(metadataLink), selectClause);
            }

            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,
                    EntitySet       = targetEntitySet,
                    Model           = model,
                    RootElementName = GetRootElementName(path) ?? "root",
                    SkipExpensiveAvailabilityChecks = serializer.ODataPayloadKind == ODataPayloadKind.Feed,
                    Path               = path,
                    MetadataLevel      = ODataMediaTypes.GetMetadataLevel(contentType),
                    SelectExpandClause = Request.GetSelectExpandClause()
                };

                serializer.WriteObject(value, type, messageWriter, writeContext);
            }
        }
Example #3
0
 public void GetMetadataLevel_Returns_Correct_MetadataLevel(string contentType, object metadataLevel)
 {
     Assert.Equal(
         metadataLevel,
         ODataMediaTypes.GetMetadataLevel(MediaTypeHeaderValue.Parse(contentType)));
 }