Ejemplo n.º 1
0
        internal static IODataResponseMessage PrepareResponseMessage(IWebApiRequestMessage internalRequest, IWebApiHeaders internalRequestHeaders, Func <IServiceProvider, ODataMessageWrapper> getODataMessageWrapper)
        {
            string preferHeader     = RequestPreferenceHelpers.GetRequestPreferHeader(internalRequestHeaders);
            string annotationFilter = null;
            string omitValues       = null;
            int?   maxPageSize      = null;

            if (!String.IsNullOrEmpty(preferHeader))
            {
                ODataMessageWrapper messageWrapper = getODataMessageWrapper(null);
                messageWrapper.SetHeader(RequestPreferenceHelpers.PreferHeaderName, preferHeader);
                annotationFilter = messageWrapper.PreferHeader().AnnotationFilter;
                omitValues       = messageWrapper.PreferHeader().OmitValues;
                maxPageSize      = messageWrapper.PreferHeader().MaxPageSize;
            }

            IODataResponseMessage responseMessage = getODataMessageWrapper(internalRequest.RequestContainer);

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

            if (omitValues != null)
            {
                responseMessage.PreferenceAppliedHeader().OmitValues = omitValues;
            }

            if (maxPageSize != null)
            {
                responseMessage.PreferenceAppliedHeader().MaxPageSize = maxPageSize;
            }

            return(responseMessage);
        }
Ejemplo n.º 2
0
        internal static bool CanWriteType(
            Type type,
            IEnumerable <ODataPayloadKind> payloadKinds,
            bool isGenericSingleResult,
            IWebApiRequestMessage internalRequest,
            Func <Type, ODataSerializer> getODataPayloadSerializer)
        {
            if (type == null)
            {
                throw Error.ArgumentNull("type");
            }

            ODataPayloadKind?payloadKind;

            Type elementType;

            if (typeof(IEdmObject).IsAssignableFrom(type) ||
                (TypeHelper.IsCollection(type, out elementType) && typeof(IEdmObject).IsAssignableFrom(elementType)))
            {
                payloadKind = GetEdmObjectPayloadKind(type, internalRequest);
            }
            else
            {
                payloadKind = GetClrObjectResponsePayloadKind(type, isGenericSingleResult, getODataPayloadSerializer);
            }

            return(payloadKind == null ? false : payloadKinds.Contains(payloadKind.Value));
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Execute the query.
        /// </summary>
        /// <param name="responseValue">The response value.</param>
        /// <param name="singleResultCollection">The content as SingleResult.Queryable.</param>
        /// <param name="actionDescriptor">The action context, i.e. action and controller name.</param>
        /// <param name="modelFunction">A function to get the model.</param>
        /// <param name="request">The internal request.</param>
        /// <param name="createQueryOptionFunction">A function used to create and validate query options.</param>
        /// <returns></returns>
        private object ExecuteQuery(
            object responseValue,
            IQueryable singleResultCollection,
            IWebApiActionDescriptor actionDescriptor,
            Func <Type, IEdmModel> modelFunction,
            IWebApiRequestMessage request,
            Func <ODataQueryContext, IODataQueryOptions> createQueryOptionFunction)
        {
            ODataQueryContext queryContext = GetODataQueryContext(responseValue, singleResultCollection, actionDescriptor, modelFunction, request.Context.Path);

            // Create and validate the query options.
            IODataQueryOptions queryOptions = createQueryOptionFunction(queryContext);

            // apply the query
            IEnumerable enumerable = responseValue as IEnumerable;

            if (enumerable == null || responseValue is string || responseValue is byte[])
            {
                // response is not a collection; we only support $select and $expand on single entities.
                ValidateSelectExpandOnly(queryOptions);

                if (singleResultCollection == null)
                {
                    // response is a single entity.
                    return(ApplyQuery(entity: responseValue, queryOptions: queryOptions));
                }
                else
                {
                    IQueryable queryable = singleResultCollection as IQueryable;
                    queryable = ApplyQuery(queryable, queryOptions);
                    return(SingleOrDefault(queryable, actionDescriptor));
                }
            }
            else
            {
                // response is a collection.
                IQueryable queryable = (enumerable as IQueryable) ?? enumerable.AsQueryable();
                queryable = ApplyQuery(queryable, queryOptions);

                if (request.IsCountRequest())
                {
                    long?count = request.Context.TotalCount;

                    if (count.HasValue)
                    {
                        // Return the count value if it is a $count request.
                        return(count.Value);
                    }
                }

                return(queryable);
            }
        }
        internal static object ReadFromStream(
            Type type,
            object defaultValue,
            IEdmModel model,
            Uri baseAddress,
            IWebApiRequestMessage internalRequest,
            Func <IODataRequestMessage> getODataRequestMessage,
            Func <IEdmTypeReference, ODataDeserializer> getEdmTypeDeserializer,
            Func <Type, ODataDeserializer> getODataPayloadDeserializer,
            Func <ODataDeserializerContext> getODataDeserializerContext,
            Action <IDisposable> registerForDisposeAction,
            Action <Exception> logErrorAction)
        {
            object result;

            IEdmTypeReference expectedPayloadType;
            ODataDeserializer deserializer = GetDeserializer(type, internalRequest.Context.Path, model, getEdmTypeDeserializer, getODataPayloadDeserializer, out expectedPayloadType);

            if (deserializer == null)
            {
                throw Error.Argument("type", SRResources.FormatterReadIsNotSupportedForType, type.FullName, typeof(ODataInputFormatterHelper).FullName);
            }

            try
            {
                ODataMessageReaderSettings oDataReaderSettings = internalRequest.ReaderSettings;
                oDataReaderSettings.BaseUri     = baseAddress;
                oDataReaderSettings.Validations = oDataReaderSettings.Validations & ~ValidationKinds.ThrowOnUndeclaredPropertyForNonOpenType;

                IODataRequestMessage oDataRequestMessage = getODataRequestMessage();
                ODataMessageReader   oDataMessageReader  = new ODataMessageReader(oDataRequestMessage, oDataReaderSettings, model);
                registerForDisposeAction(oDataMessageReader);

                ODataPath path = internalRequest.Context.Path;
                ODataDeserializerContext readContext = getODataDeserializerContext();
                readContext.Path            = path;
                readContext.Model           = model;
                readContext.ResourceType    = type;
                readContext.ResourceEdmType = expectedPayloadType;

                result = deserializer.Read(oDataMessageReader, type, readContext);
            }
            catch (Exception e)
            {
                logErrorAction(e);
                result = defaultValue;
            }

            return(result);
        }
Ejemplo n.º 5
0
        private static object CovertResourceId(object source, ODataResource resource,
                                               IEdmEntityTypeReference entityTypeReference, ODataDeserializerContext readContext)
        {
            Contract.Assert(resource != null);
            Contract.Assert(source != null);

            if (resource.Id == null || resource.Properties.Any())
            {
                return(source);
            }

            IWebApiRequestMessage request   = readContext.InternalRequest;
            IWebApiUrlHelper      urlHelper = readContext.InternalUrlHelper;

            DefaultODataPathHandler pathHandler = new DefaultODataPathHandler();
            string serviceRoot = urlHelper.CreateODataLink(
                request.Context.RouteName,
                request.PathHandler,
                new List <ODataPathSegment>());

            IEnumerable <KeyValuePair <string, object> > keyValues = GetKeys(pathHandler, serviceRoot, resource.Id,
                                                                             request.RequestContainer);

            IList <IEdmStructuralProperty> keys = entityTypeReference.Key().ToList();

            if (keys.Count == 1 && keyValues.Count() == 1)
            {
                // TODO: make sure the enum key works
                object propertyValue = keyValues.First().Value;
                DeserializationHelpers.SetDeclaredProperty(source, EdmTypeKind.Primitive, keys[0].Name, propertyValue,
                                                           keys[0], readContext);
                return(source);
            }

            IDictionary <string, object> keyValuesDic = keyValues.ToDictionary(e => e.Key, e => e.Value);

            foreach (IEdmStructuralProperty key in keys)
            {
                object value;
                if (keyValuesDic.TryGetValue(key.Name, out value))
                {
                    // TODO: make sure the enum key works
                    DeserializationHelpers.SetDeclaredProperty(source, EdmTypeKind.Primitive, key.Name, value, key,
                                                               readContext);
                }
            }

            return(source);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Returns the request method and in the case of Options request it returns the Access-Control-Request-Method present in the
        /// preflight request for the request method that will be used for the actual request
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        internal static ODataRequestMethod GetRequestMethodOrPreflightMethod(this IWebApiRequestMessage request)
        {
            if (request.Method != ODataRequestMethod.Options)
            {
                return(request.Method);
            }

            IEnumerable <string> values;

            if (!request.Headers.TryGetValues("Access-Control-Request-Method", out values))
            {
                return(ODataRequestMethod.Unknown);
            }

            ODataRequestMethod preflightMethod;

            return(Enum.TryParse <ODataRequestMethod>(values.FirstOrDefault(), true, out preflightMethod) ? preflightMethod : ODataRequestMethod.Unknown);
        }
Ejemplo n.º 7
0
        private static ODataSerializer GetSerializer(Type type, object value, IWebApiRequestMessage internalRequest, Func <IEdmTypeReference, ODataSerializer> getEdmTypeSerializer, Func <Type, ODataSerializer> getODataPayloadSerializer)
        {
            ODataSerializer serializer;

            IEdmObject edmObject = value as IEdmObject;

            if (edmObject != null)
            {
                IEdmTypeReference edmType = edmObject.GetEdmType();
                if (edmType == null)
                {
                    throw new SerializationException(Error.Format(SRResources.EdmTypeCannotBeNull,
                                                                  edmObject.GetType().FullName, typeof(IEdmObject).Name));
                }

                serializer = getEdmTypeSerializer(edmType);
                if (serializer == null)
                {
                    string message = Error.Format(SRResources.TypeCannotBeSerialized, edmType.ToTraceString());
                    throw new SerializationException(message);
                }
            }
            else
            {
                var applyClause = internalRequest.Context.ApplyClause;
                // get the most appropriate serializer given that we support inheritance.
                if (applyClause == null)
                {
                    type = value == null ? type : value.GetType();
                }

                serializer = getODataPayloadSerializer(type);
                if (serializer == null)
                {
                    string message = Error.Format(SRResources.TypeCannotBeSerialized, type.Name);
                    throw new SerializationException(message);
                }
            }

            return(serializer);
        }
Ejemplo n.º 8
0
        private static ODataPayloadKind?GetEdmObjectPayloadKind(Type type, IWebApiRequestMessage internalRequest)
        {
            if (internalRequest.IsCountRequest())
            {
                return(ODataPayloadKind.Value);
            }

            Type elementType;

            if (TypeHelper.IsCollection(type, out elementType))
            {
                if (typeof(IEdmComplexObject).IsAssignableFrom(elementType) || typeof(IEdmEnumObject).IsAssignableFrom(elementType))
                {
                    return(ODataPayloadKind.Collection);
                }
                else if (typeof(IEdmEntityObject).IsAssignableFrom(elementType))
                {
                    return(ODataPayloadKind.ResourceSet);
                }
                else if (typeof(IEdmChangedObject).IsAssignableFrom(elementType))
                {
                    return(ODataPayloadKind.Delta);
                }
            }
            else
            {
                if (typeof(IEdmComplexObject).IsAssignableFrom(elementType) || typeof(IEdmEnumObject).IsAssignableFrom(elementType))
                {
                    return(ODataPayloadKind.Property);
                }
                else if (typeof(IEdmEntityObject).IsAssignableFrom(elementType))
                {
                    return(ODataPayloadKind.Resource);
                }
            }

            return(null);
        }
Ejemplo n.º 9
0
        private static object ConvertResourceOrResourceSet(object oDataValue, IEdmTypeReference edmTypeReference,
                                                           ODataDeserializerContext readContext)
        {
            string valueString = oDataValue as string;

            Contract.Assert(valueString != null);

            if (edmTypeReference.IsNullable && String.Equals(valueString, "null", StringComparison.Ordinal))
            {
                return(null);
            }

            IWebApiRequestMessage      request             = readContext.InternalRequest;
            ODataMessageReaderSettings oDataReaderSettings = request.ReaderSettings;

            using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(valueString)))
            {
                stream.Seek(0, SeekOrigin.Begin);

                IODataRequestMessage oDataRequestMessage = new ODataMessageWrapper(stream, null,
                                                                                   request.ODataContentIdMapping);
                using (
                    ODataMessageReader oDataMessageReader = new ODataMessageReader(oDataRequestMessage,
                                                                                   oDataReaderSettings, readContext.Model))
                {
                    if (edmTypeReference.IsCollection())
                    {
                        return(ConvertResourceSet(oDataMessageReader, edmTypeReference, readContext));
                    }
                    else
                    {
                        return(ConvertResource(oDataMessageReader, edmTypeReference, readContext));
                    }
                }
            }
        }
Ejemplo n.º 10
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);
            }
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Selects the controller for OData requests.
        /// </summary>
        /// <param name="odataPath">The OData path.</param>
        /// <param name="request">The request.</param>
        /// <returns>
        ///   <c>null</c> if the request isn't handled by this convention; otherwise, the name of the selected controller
        /// </returns>
        internal static SelectControllerResult SelectControllerImpl(ODataPath odataPath, IWebApiRequestMessage request)
        {
            if (odataPath == null)
            {
                throw Error.ArgumentNull("odataPath");
            }

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

            if (odataPath.PathTemplate == "~" ||
                odataPath.PathTemplate == "~/$metadata")
            {
                return(new SelectControllerResult("Metadata", null));
            }

            return(null);
        }
Ejemplo n.º 12
0
        /// <inheritdoc />
        internal static SelectControllerResult SelectControllerImpl(ODataPath odataPath, IWebApiRequestMessage request,
                                                                    IDictionary <ODataPathTemplate, IWebApiActionDescriptor> attributeMappings)
        {
            Dictionary <string, object> values = new Dictionary <string, object>();

            foreach (KeyValuePair <ODataPathTemplate, IWebApiActionDescriptor> attributeMapping in attributeMappings)
            {
                ODataPathTemplate       template = attributeMapping.Key;
                IWebApiActionDescriptor action   = attributeMapping.Value;

                if (action.IsHttpMethodSupported(request.GetRequestMethodOrPreflightMethod()) && template.TryMatch(odataPath, values))
                {
                    values["action"] = action.ActionName;
                    SelectControllerResult result = new SelectControllerResult(action.ControllerName, values);

                    return(result);
                }
            }

            return(null);
        }
Ejemplo n.º 13
0
        internal static object ReadFromStream(
#endif
            Type type,
            object defaultValue,
            IEdmModel model,
            ODataVersion version,
            Uri baseAddress,
            IWebApiRequestMessage internalRequest,
            Func <IODataRequestMessage> getODataRequestMessage,
            Func <IEdmTypeReference, ODataDeserializer> getEdmTypeDeserializer,
            Func <Type, ODataDeserializer> getODataPayloadDeserializer,
            Func <ODataDeserializerContext> getODataDeserializerContext,
            Action <IDisposable> registerForDisposeAction,
            Action <Exception> logErrorAction)
        {
            object result;

            IEdmTypeReference expectedPayloadType;
            ODataDeserializer deserializer = GetDeserializer(type, internalRequest.Context.Path, model, getEdmTypeDeserializer, getODataPayloadDeserializer, out expectedPayloadType);

            if (deserializer == null)
            {
                throw Error.Argument("type", SRResources.FormatterReadIsNotSupportedForType, type.FullName, typeof(ODataInputFormatterHelper).FullName);
            }

            try
            {
                ODataMessageReaderSettings oDataReaderSettings = internalRequest.ReaderSettings;
                oDataReaderSettings.BaseUri     = baseAddress;
                oDataReaderSettings.Validations = oDataReaderSettings.Validations & ~ValidationKinds.ThrowOnUndeclaredPropertyForNonOpenType;
                oDataReaderSettings.Version     = version;

                IODataRequestMessage oDataRequestMessage = getODataRequestMessage();

                string preferHeader     = RequestPreferenceHelpers.GetRequestPreferHeader(internalRequest.Headers);
                string annotationFilter = null;
                if (!String.IsNullOrEmpty(preferHeader))
                {
                    oDataRequestMessage.SetHeader(RequestPreferenceHelpers.PreferHeaderName, preferHeader);
                    annotationFilter = oDataRequestMessage.PreferHeader().AnnotationFilter;
                }

                if (annotationFilter != null)
                {
                    oDataReaderSettings.ShouldIncludeAnnotation = ODataUtils.CreateAnnotationFilter(annotationFilter);
                }

                ODataMessageReader oDataMessageReader = new ODataMessageReader(oDataRequestMessage, oDataReaderSettings, model);
                registerForDisposeAction(oDataMessageReader);

                ODataPath path = internalRequest.Context.Path;
                ODataDeserializerContext readContext = getODataDeserializerContext();
                readContext.Path            = path;
                readContext.Model           = model;
                readContext.ResourceType    = type;
                readContext.ResourceEdmType = expectedPayloadType;

#if NETCORE
                result = await deserializer.ReadAsync(oDataMessageReader, type, readContext);
#else
                result = deserializer.Read(oDataMessageReader, type, readContext);
#endif
            }
            catch (Exception e)
            {
                logErrorAction(e);
                result = defaultValue;
            }

            return(result);
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Performs the query composition after action is executed. It first tries to retrieve the IQueryable from the
        /// returning response message. It then validates the query from uri based on the validation settings on
        /// <see cref="EnableQueryAttribute"/>. It finally applies the query appropriately, and reset it back on
        /// the response message.
        /// </summary>
        /// <param name="responseValue">The response content value.</param>
        /// <param name="singleResultCollection">The content as SingleResult.Queryable.</param>
        /// <param name="actionDescriptor">The action context, i.e. action and controller name.</param>
        /// <param name="request">The internal request.</param>
        /// <param name="modelFunction">A function to get the model.</param>
        /// <param name="createQueryOptionFunction">A function used to create and validate query options.</param>
        /// <param name="createResponseAction">An action used to create a response.</param>
        /// <param name="createErrorAction">A function used to generate error response.</param>
        private object OnActionExecuted(
            object responseValue,
            IQueryable singleResultCollection,
            IWebApiActionDescriptor actionDescriptor,
            IWebApiRequestMessage request,
            Func <Type, IEdmModel> modelFunction,
            Func <ODataQueryContext, IODataQueryOptions> createQueryOptionFunction,
            Action <HttpStatusCode> createResponseAction,
            Action <HttpStatusCode, string, Exception> createErrorAction)
        {
            if (!_querySettings.PageSize.HasValue && responseValue != null)
            {
                GetModelBoundPageSize(responseValue, singleResultCollection, actionDescriptor, modelFunction, request.Context.Path, createErrorAction);
            }

            // Apply the query if there are any query options, if there is a page size set, in the case of
            // SingleResult or in the case of $count request.
            bool shouldApplyQuery = responseValue != null &&
                                    request.RequestUri != null &&
                                    (!String.IsNullOrWhiteSpace(request.RequestUri.Query) ||
                                     _querySettings.PageSize.HasValue ||
                                     _querySettings.ModelBoundPageSize.HasValue ||
                                     singleResultCollection != null ||
                                     request.IsCountRequest() ||
                                     ContainsAutoSelectExpandProperty(responseValue, singleResultCollection, actionDescriptor, modelFunction, request.Context.Path));

            object returnValue = null;

            if (shouldApplyQuery)
            {
                try
                {
                    object queryResult = ExecuteQuery(responseValue, singleResultCollection, actionDescriptor, modelFunction, request, createQueryOptionFunction);
                    if (queryResult == null && (request.Context.Path == null || singleResultCollection != null))
                    {
                        // This is the case in which a regular OData service uses the EnableQuery attribute.
                        // For OData services ODataNullValueMessageHandler should be plugged in for the service
                        // if this behavior is desired.
                        // For non OData services this behavior is equivalent as the one in the v3 version in order
                        // to reduce the friction when they decide to move to use the v4 EnableQueryAttribute.
                        createResponseAction(HttpStatusCode.NotFound);
                    }

                    returnValue = queryResult;
                }
                catch (ArgumentOutOfRangeException e)
                {
                    createErrorAction(
                        HttpStatusCode.BadRequest,
                        Error.Format(SRResources.QueryParameterNotSupported, e.Message),
                        e);
                }
                catch (NotImplementedException e)
                {
                    createErrorAction(
                        HttpStatusCode.BadRequest,
                        Error.Format(SRResources.UriQueryStringInvalid, e.Message),
                        e);
                }
                catch (NotSupportedException e)
                {
                    createErrorAction(
                        HttpStatusCode.BadRequest,
                        Error.Format(SRResources.UriQueryStringInvalid, e.Message),
                        e);
                }
                catch (InvalidOperationException e)
                {
                    // Will also catch ODataException here because ODataException derives from InvalidOperationException.
                    createErrorAction(
                        HttpStatusCode.BadRequest,
                        Error.Format(SRResources.UriQueryStringInvalid, e.Message),
                        e);
                }
            }

            return(returnValue);
        }
Ejemplo n.º 15
0
        /// <inheritdoc />
        internal static SelectControllerResult SelectControllerImpl(ODataPath odataPath, IWebApiRequestMessage request,
                                                                    IDictionary <ODataPathTemplate, IWebApiActionDescriptor> attributeMappings)
        {
            Dictionary <string, object> values = new Dictionary <string, object>();

            foreach (KeyValuePair <ODataPathTemplate, IWebApiActionDescriptor> attributeMapping in attributeMappings)
            {
                ODataPathTemplate       template = attributeMapping.Key;
                IWebApiActionDescriptor action   = attributeMapping.Value;

                if (action.IsHttpMethodSupported(request.GetRequestMethodOrPreflightMethod()) && template.TryMatch(odataPath, values))
                {
                    values["action"] = action.ActionName;
                    SelectControllerResult result = new SelectControllerResult(action.ControllerName, values);

                    return(result);
                }

                // It's possible that template.TryMatch inserted values in the values dict even if
                // it did not match the current path. So let's clear the dict before trying
                // the next template
                values.Clear();
            }

            return(null);
        }