예제 #1
0
        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);
            }
        }
예제 #2
0
        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);
            }
        }
예제 #3
0
        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 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");
            }

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

            return(TaskHelpers.RunSynchronously(() =>
            {
                // Get the format and version to use from the ODataServiceVersion content header or if not available use the
                // values configured for the specialized formatter instance.
                ODataVersion version;
                ODataFormat odataFormat;
                if (contentHeaders == null)
                {
                    version = _defaultODataVersion;
                    odataFormat = ODataFormatterConstants.DefaultODataFormat;
                }
                else
                {
                    version = GetODataVersion(contentHeaders, ODataFormatterConstants.ODataServiceVersion) ?? _defaultODataVersion;
                    odataFormat = GetODataFormat(contentHeaders);
                }

                ODataSerializer serializer = ODataSerializerProvider.GetODataPayloadSerializer(type);
                if (serializer == null)
                {
                    throw Error.InvalidOperation(SRResources.TypeCannotBeSerialized, type.Name, typeof(ODataMediaTypeFormatter).Name);
                }

                if (IsClient)
                {
                    // TODO: Bug 467617: figure out the story for the operation name on the client side and server side.
                    string operationName = (value != null ? value.GetType() : type).Name;

                    // serialize a request
                    IODataRequestMessage requestMessage = new ODataMessageWrapper(writeStream);
                    ODataResponseContext responseContext = new ODataResponseContext(requestMessage, odataFormat, version, new Uri(ODataFormatterConstants.DefaultNamespace), operationName);

                    ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings()
                    {
                        BaseUri = responseContext.BaseAddress,
                        Version = responseContext.ODataVersion,
                        Indent = responseContext.IsIndented,
                        DisableMessageStreamDisposal = true,
                    };

                    writerSettings.SetContentType(responseContext.ODataFormat);
                    using (ODataMessageWriter messageWriter = new ODataMessageWriter(requestMessage, writerSettings, Model))
                    {
                        ODataSerializerWriteContext writeContext = new ODataSerializerWriteContext(responseContext);
                        serializer.WriteObject(value, messageWriter, writeContext);
                    }
                }
                else
                {
                    UrlHelper urlHelper = Request.GetUrlHelper();
                    NameValueCollection queryStringValues = Request.RequestUri.ParseQueryString();

                    IEdmEntitySet targetEntitySet = null;
                    ODataUriHelpers.TryGetEntitySetAndEntityType(Request.RequestUri, Model, out targetEntitySet);

                    ODataQueryProjectionNode rootProjectionNode = null;
                    if (targetEntitySet != null)
                    {
                        // TODO: Bug 467621: Move to ODataUriParser once it is done.
                        rootProjectionNode = ODataUriHelpers.GetODataQueryProjectionNode(queryStringValues["$select"], queryStringValues["$expand"], targetEntitySet);
                    }

                    // serialize a response
                    Uri baseAddress = new Uri(Request.RequestUri, Request.GetConfiguration().VirtualPathRoot);

                    // TODO: Bug 467617: figure out the story for the operation name on the client side and server side.
                    // This is clearly a workaround. We are assuming that the operation name is the last segment in the request uri
                    // which works for most cases and fall back to the type name of the object being written.
                    // We should rather use uri parser semantic tree to figure out the operation name from the request url.
                    string operationName = ODataUriHelpers.GetOperationName(Request.RequestUri, baseAddress);
                    operationName = operationName ?? type.Name;

                    IODataResponseMessage responseMessage = new ODataMessageWrapper(writeStream);
                    ODataResponseContext responseContext = new ODataResponseContext(responseMessage, odataFormat, version, baseAddress, operationName);

                    ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings()
                    {
                        BaseUri = responseContext.BaseAddress,
                        Version = responseContext.ODataVersion,
                        Indent = responseContext.IsIndented,
                        DisableMessageStreamDisposal = true,
                    };
                    if (contentHeaders != null && contentHeaders.ContentType != null)
                    {
                        writerSettings.SetContentType(contentHeaders.ContentType.ToString(), Encoding.UTF8.WebName);
                    }

                    using (ODataMessageWriter messageWriter = new ODataMessageWriter(responseMessage, writerSettings, ODataDeserializerProvider.EdmModel))
                    {
                        ODataSerializerWriteContext writeContext = new ODataSerializerWriteContext(responseContext)
                        {
                            EntitySet = targetEntitySet,
                            UrlHelper = urlHelper,
                            RootProjectionNode = rootProjectionNode,
                            CurrentProjectionNode = rootProjectionNode
                        };

                        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);
            }
        }
예제 #6
0
        private void WriteResponseBody(OutputFormatterWriteContext context)
        {
            HttpContext  httpContext = context.HttpContext;
            HttpRequest  request     = context.HttpContext.Request;
            HttpResponse response    = context.HttpContext.Response;

            IEdmModel model = context.HttpContext.ODataFeature().Model;

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

            object value        = null;
            object graph        = null;
            var    objectResult = context.Object as PageResult <object>;

            if (objectResult != null)
            {
                value = objectResult.Items;
                graph = objectResult;
            }
            else
            {
                value = context.Object;
                graph = value;
            }
            var type = value.GetType();

            ODataSerializer serializer = GetSerializer(type, value, context);

            IUrlHelper urlHelper = context.HttpContext.UrlHelper();

            ODataPath            path = httpContext.ODataFeature().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 = _messageWriterSettings.Clone();

            writerSettings.BaseUri     = baseAddress;
            writerSettings.Version     = ODataVersion.V4;
            writerSettings.Validations = writerSettings.Validations & ~ValidationKinds.ThrowOnUndeclaredPropertyForNonOpenType;

            string metadataLink = urlHelper.CreateODataLink(request, MetadataSegment.Instance);

            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 = httpContext.ODataFeature().SelectExpandClause,
                Path            = (path == null) ? null : path.ODLPath
                                  //Path = (path == null || IsOperationPath(path)) ? null : path.ODLPath,
            };

            using (ODataMessageWriter messageWriter = new ODataMessageWriter(responseMessage, writerSettings, model))
            {
                ODataSerializerContext writeContext = new ODataSerializerContext()
                {
                    Context          = context.HttpContext,
                    Url              = urlHelper,
                    NavigationSource = targetNavigationSource,
                    Model            = model,
                    RootElementName  = GetRootElementName(path) ?? "root",
                    SkipExpensiveAvailabilityChecks = serializer.ODataPayloadKind == ODataPayloadKind.ResourceSet,
                    Path               = path,
                    MetadataLevel      = ODataMediaTypes.GetMetadataLevel(MediaTypeHeaderValue.Parse(context.ContentType.Value)),
                    SelectExpandClause = request.ODataFeature().SelectExpandClause,
                };

                serializer.WriteObject(graph, type, messageWriter, writeContext);
            }
        }
예제 #7
0
        internal static void WriteToStream(
            Type type,
            object value,
            IEdmModel model,
            ODataVersion version,
            Uri baseAddress,
            MediaTypeHeaderValue contentType,
            HttpRequest request,
            IHeaderDictionary requestHeaders,
            ODataSerializerProvider serializerProvider)
        {
            if (model == null)
            {
                throw Error.InvalidOperation(SRResources.RequestMustHaveModel);
            }

            ODataSerializer serializer = GetSerializer(type, value, request, serializerProvider);

            ODataPath            path = request.ODataFeature().Path;
            IEdmNavigationSource targetNavigationSource = path == null ? null : path.GetNavigationSource();
            HttpResponse         response = request.HttpContext.Response;

            // serialize a response
            string preferHeader     = RequestPreferenceHelpers.GetRequestPreferHeader(requestHeaders);
            string annotationFilter = null;

            if (!string.IsNullOrEmpty(preferHeader))
            {
                ODataMessageWrapper messageWrapper = ODataMessageWrapperHelper.Create(response.Body, response.Headers);
                messageWrapper.SetHeader(RequestPreferenceHelpers.PreferHeaderName, preferHeader);
                annotationFilter = messageWrapper.PreferHeader().AnnotationFilter;
            }

            IODataResponseMessage responseMessage = ODataMessageWrapperHelper.Create(response.Body, response.Headers, request.GetSubServiceProvider());

            if (annotationFilter != null)
            {
                responseMessage.PreferenceAppliedHeader().AnnotationFilter = annotationFilter;
            }

            ODataMessageWriterSettings writerSettings = request.GetWriterSettings();

            writerSettings.BaseUri     = baseAddress;
            writerSettings.Version     = version;
            writerSettings.Validations = writerSettings.Validations & ~ValidationKinds.ThrowOnUndeclaredPropertyForNonOpenType;

            string metadataLink = request.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;
            ODataQueryOptions  queryOptions = request.GetQueryOptions();
            SelectExpandClause processedSelectExpandClause = request.ODataFeature().SelectExpandClause;

            if (queryOptions != null && queryOptions.SelectExpand != null)
            {
                if (queryOptions.SelectExpand.ProcessedSelectExpandClause != processedSelectExpandClause)
                {
                    selectExpandDifferentFromQueryOptions = processedSelectExpandClause;
                }
            }
            else if (processedSelectExpandClause != null)
            {
                selectExpandDifferentFromQueryOptions = processedSelectExpandClause;
            }

            writerSettings.ODataUri = new ODataUri
            {
                ServiceRoot = baseAddress,

                // TODO: 1604 Convert webapi.odata's ODataPath to ODL's ODataPath, or use ODL's ODataPath.
                SelectAndExpand = processedSelectExpandClause,
                Apply           = request.ODataFeature().ApplyClause,
                //Path = (path == null || IsOperationPath(path)) ? null : path.Path,
                Path = path
            };

            ODataMetadataLevel metadataLevel = ODataMetadataLevel.Minimal;

            if (contentType != null)
            {
                IEnumerable <KeyValuePair <string, string> > parameters =
                    contentType.Parameters.Select(val => new KeyValuePair <string, string>(val.Name.ToString(),
                                                                                           val.Value.ToString()));
                metadataLevel = ODataMediaTypes.GetMetadataLevel(contentType.MediaType.ToString(), parameters);
            }

            using (ODataMessageWriter messageWriter = new ODataMessageWriter(responseMessage, writerSettings, model))
            {
                ODataSerializerContext writeContext = BuildSerializerContext(request);
                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  = queryOptions;

                //Set the SelectExpandClause on the context if it was explicitly specified.
                if (selectExpandDifferentFromQueryOptions != null)
                {
                    writeContext.SelectExpandClause = selectExpandDifferentFromQueryOptions;
                }

                serializer.WriteObject(value, type, messageWriter, writeContext);
            }
        }
예제 #8
0
        public void WriteJson(object value, Stream writeStream)
        {
            IEdmModel model = _odataProperties.Model;

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

            var type = value.GetType();

            type = _context.ObjectType;
            ODataSerializer serializer = GetSerializer(type, value, model, DefaultODataSerializerProvider.Instance);

            var                  urlHelper = UrlHelper(_context.HttpContext);
            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);
            //}

            // TODO: Fix this ffs...

            string preferHeader     = RequestPreferenceHelpers.GetRequestPreferHeader(Request);
            string annotationFilter = null;

            if (ODataCountMediaTypeMapping.IsCountRequest(Request))
            {
                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(MessageWriterSettings)
            {
                PayloadBaseUri = baseAddress,
                Version        = _version,
            };

            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,
                // TODO: Support $apply
                //Apply = Request.ODataProperties().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))
            {
                ODataSerializerContext writeContext = new ODataSerializerContext()
                {
                    Request          = Request,
                    RequestContext   = _context.HttpContext,
                    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);
            }
        }
        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);
                }
            }));
        }
        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.NotSupported(SRResources.WriteToStreamAsyncMustHaveRequest);
            }

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

            return(TaskHelpers.RunSynchronously(() =>
            {
                // get the most appropriate serializer given that we support inheritance.
                type = value == null ? type : value.GetType();
                ODataSerializer serializer = _serializerProvider.GetODataPayloadSerializer(type);
                if (serializer == null)
                {
                    throw Error.InvalidOperation(SRResources.TypeCannotBeSerialized, type.Name, typeof(ODataMediaTypeFormatter).Name);
                }

                UrlHelper urlHelper = _request.GetUrlHelper();

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

                // serialize a response
                HttpConfiguration configuration = _request.GetConfiguration();
                Uri baseAddress = new Uri(_request.RequestUri, configuration.VirtualPathRoot);

                IODataResponseMessage responseMessage = new ODataMessageWrapper(writeStream);

                // TODO: Issue 483: http://aspnetwebstack.codeplex.com/workitem/483
                // We need to set the MetadataDocumentUri when this property is added to ODataMessageWriterSettings as
                // part of the JSON Light work.
                // This is required so ODataLib can coerce AbsoluteUri's into RelativeUri's when appropriate in JSON Light.
                ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings()
                {
                    BaseUri = baseAddress,
                    Version = _version,
                    Indent = true,
                    DisableMessageStreamDisposal = true
                };

                if (contentHeaders != null && contentHeaders.ContentType != null)
                {
                    MediaTypeHeaderValue contentType = contentHeaders.ContentType;
                    writerSettings.SetContentType(contentType.ToString(), contentType.CharSet);
                }

                using (ODataMessageWriter messageWriter = new ODataMessageWriter(responseMessage, writerSettings, _deserializerProvider.EdmModel))
                {
                    ODataSerializerContext writeContext = new ODataSerializerContext()
                    {
                        EntitySet = targetEntitySet,
                        UrlHelper = urlHelper,
                        PathHandler = configuration.GetODataPathHandler() ?? new DefaultODataPathHandler(Model),
                        RootElementName = GetRootElementName(path) ?? ElementNameDefault,
                        SkipExpensiveAvailabilityChecks = serializer.ODataPayloadKind == ODataPayloadKind.Feed,
                        Request = _request
                    };

                    serializer.WriteObject(value, messageWriter, writeContext);
                }
            }));
        }
 public override void WriteObject(object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext)
 {
     _logger.LogDebug("[ODataPayloadSerializer.WriteObject] type: " + type);
     _serializer.WriteObject(graph, type, messageWriter, writeContext);
 }
예제 #12
0
        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;
            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)
            {
                PayloadBaseUri = GetBaseAddress(Request),
                Version        = _version,
            };

            string metadataLink = urlHelper.CreateODataLink(new MetadataPathSegment());

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

            string resourcePath = path != null?path.ToString() : String.Empty;

            Uri baseAddress = GetBaseAddress(Request);

            writerSettings.SetServiceDocumentUri(
                baseAddress,
                Request.ODataProperties().SelectExpandClause,
                resourcePath,
                isIndividualProperty: false);

            writerSettings.ODataUri = new ODataUri
            {
                ServiceRoot = baseAddress,

                // TODO: 1604 Convert webapi.odata's ODataPath to ODL's ODataPath, or use ODL's ODataPath.
            };

            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.ODataProperties().SelectExpandClause
                };

                serializer.WriteObject(value, type, messageWriter, writeContext);
            }
        }
예제 #13
0
        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.NotSupported(SRResources.WriteToStreamAsyncMustHaveRequest);
            }

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

            return(TaskHelpers.RunSynchronously(() =>
            {
                // Get the format and version to use from the ODataServiceVersion content header or if not available use the
                // values configured for the specialized formatter instance.
                ODataVersion version;
                if (contentHeaders == null)
                {
                    version = _defaultODataVersion;
                }
                else
                {
                    version = GetODataVersion(contentHeaders, ODataFormatterConstants.ODataServiceVersion) ?? _defaultODataVersion;
                }

                // get the most appropriate serializer given that we support inheritance.
                type = value == null ? type : value.GetType();
                ODataSerializer serializer = ODataSerializerProvider.GetODataPayloadSerializer(type);
                if (serializer == null)
                {
                    throw Error.InvalidOperation(SRResources.TypeCannotBeSerialized, type.Name, typeof(ODataMediaTypeFormatter).Name);
                }

                UrlHelper urlHelper = Request.GetUrlHelper();

                IEdmEntitySet targetEntitySet = null;
                ODataUriHelpers.TryGetEntitySetAndEntityType(Request.RequestUri, Model, out targetEntitySet);

                // serialize a response
                Uri baseAddress = new Uri(Request.RequestUri, Request.GetConfiguration().VirtualPathRoot);

                // TODO: Bug 467617: figure out the story for the operation name on the client side and server side.
                // This is clearly a workaround. We are assuming that the operation name is the last segment in the request uri
                // which works for most cases and fall back to the type name of the object being written.
                // We should rather use uri parser semantic tree to figure out the operation name from the request url.
                string operationName = ODataUriHelpers.GetOperationName(Request.RequestUri, baseAddress);
                operationName = operationName ?? type.Name;

                IODataResponseMessage responseMessage = new ODataMessageWrapper(writeStream);

                // TODO: Issue 483: http://aspnetwebstack.codeplex.com/workitem/483
                // We need to set the MetadataDocumentUri when this property is added to ODataMessageWriterSettings as
                // part of the JSON Light work.
                // This is required so ODataLib can coerce AbsoluteUri's into RelativeUri's when appropriate in JSON Light.
                ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings()
                {
                    BaseUri = baseAddress,
                    Version = version,
                    Indent = true,
                    DisableMessageStreamDisposal = true
                };

                if (contentHeaders != null && contentHeaders.ContentType != null)
                {
                    writerSettings.SetContentType(contentHeaders.ContentType.ToString(), Encoding.UTF8.WebName);
                }

                using (ODataMessageWriter messageWriter = new ODataMessageWriter(responseMessage, writerSettings, ODataDeserializerProvider.EdmModel))
                {
                    ODataSerializerContext writeContext = new ODataSerializerContext()
                    {
                        EntitySet = targetEntitySet,
                        UrlHelper = urlHelper,
                        ServiceOperationName = operationName,
                        SkipExpensiveAvailabilityChecks = serializer.ODataPayloadKind == ODataPayloadKind.Feed,
                        Request = Request
                    };

                    serializer.WriteObject(value, messageWriter, writeContext);
                }
            }));
        }
예제 #14
0
        private void WriteResponseBody(OutputFormatterWriteContext context)
        {
            HttpContext  httpContext = context.HttpContext;
            HttpRequest  request     = context.HttpContext.Request;
            HttpResponse response    = context.HttpContext.Response;

            IEdmModel model = context.HttpContext.ODataFeature().Model;

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

            object value        = null;
            object graph        = null;
            var    objectResult = context.Object as PageResult <object>;

            if (objectResult != null)
            {
                value = objectResult.Items;
                graph = objectResult;
            }
            else
            {
                value = context.Object;
                graph = value;
            }
            var type = value.GetType();

            ODataSerializer serializer = GetSerializer(type, value, context);

            IUrlHelper urlHelper = context.HttpContext.UrlHelper();

            ODataPath            path = httpContext.ODataFeature().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 = _messageWriterSettings.Clone();

            writerSettings.BaseUri     = baseAddress;
            writerSettings.Version     = ODataVersion.V4;
            writerSettings.Validations = writerSettings.Validations & ~ValidationKinds.ThrowOnUndeclaredPropertyForNonOpenType;

            string metadataLink = urlHelper.CreateODataLink(request, MetadataSegment.Instance);

            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 = httpContext.ODataFeature().SelectExpandClause,
                Path            = (path == null) ? null : path.ODLPath
                                  //Path = (path == null || IsOperationPath(path)) ? null : path.ODLPath,
            };

            #region 为OData添加缓存  使用的EF二级缓存 这里是先从缓存获取数据
            //var queryResult = graph as IQueryable;
            //PageResult<object> target = null;
            //if (queryResult == null)
            //{
            //    target = graph as PageResult<object>;
            //    if (target != null) queryResult = target.Items.AsQueryable();
            //}
            //var isReadCache = queryResult != null || target != null;

            //var cacheValue = isReadCache?queryResult.CacheResult(context.HttpContext.RequestServices):null;

            //if (isReadCache&&target != null && cacheValue != null)
            //{
            //    var pageResult = cacheValue as IEnumerable<object>;
            //    //long? count = target.Count.HasValue ? (long?)pageResult.LongCount() : null;
            //    cacheValue = new PageResult<object>(pageResult, null, target.Count);
            //}

            //if (isReadCache&&cacheValue != null) graph = cacheValue;

            #endregion

            using (ODataMessageWriter messageWriter = new ODataMessageWriter(responseMessage, writerSettings, model))
            {
                ODataSerializerContext writeContext = new ODataSerializerContext()
                {
                    Context          = context.HttpContext,
                    Url              = urlHelper,
                    NavigationSource = targetNavigationSource,
                    Model            = model,
                    RootElementName  = GetRootElementName(path) ?? "root",
                    SkipExpensiveAvailabilityChecks = serializer.ODataPayloadKind == ODataPayloadKind.ResourceSet,
                    Path               = path,
                    MetadataLevel      = ODataMediaTypes.GetMetadataLevel(MediaTypeHeaderValue.Parse(context.ContentType.Value)),
                    SelectExpandClause = request.ODataFeature().SelectExpandClause,
                };

                serializer.WriteObject(graph, type, messageWriter, writeContext);

                #region 这里是往缓存中 存储数据
                //if (isReadCache&&cacheValue == null)
                //{
                //    writeContext.Context.Response.Body.Position = 0;
                //    StreamReader reder = new StreamReader(writeContext.Context.Response.Body);
                //    var bodyStr = reder.ReadToEnd();
                //    JObject.Parse(bodyStr).TryGetValue("value",out JToken values);
                //    cacheValue = values.ToObject(type.MarkListType());

                //    queryResult.CacheQuerable(cacheValue, writeContext.Context.RequestServices);
                //}
                #endregion
            }
        }