Example #1
0
        /// <summary>
        /// Returns a test instance of one of the provider OM types.
        /// </summary>
        /// <param name="type">The type to get instance of.</param>
        /// <returns>The </returns>
        public static object GetTestInstance(Type type)
        {
            if (type == typeof(ResourceType))
            {
                ResourceProperty p = new ResourceProperty("ID", ResourcePropertyKind.Primitive | ResourcePropertyKind.Key, ResourceType.GetPrimitiveResourceType(typeof(int))) { CanReflectOnInstanceTypeProperty = false };
                ResourceType resourceType = new ResourceType(typeof(object), ResourceTypeKind.EntityType, null, "Foo", "NoBaseType", false);
                Assert.IsTrue(resourceType.KeyProperties.Count == 0, "It's okay not to have key properties, since we haven't set this type to readonly yet");
                resourceType.AddProperty(p);
                return resourceType;
            }
            else if (type == typeof(ResourceProperty))
            {
                return new ResourceProperty("NonKeyProperty", ResourcePropertyKind.Primitive, ResourceType.GetPrimitiveResourceType(typeof(int)));
            }
            else if (type == typeof(ServiceOperation))
            {
                ServiceOperationParameter parameter = new ServiceOperationParameter("o", ResourceType.GetPrimitiveResourceType(typeof(string)));
                ServiceOperation operation = new ServiceOperation("Dummy", ServiceOperationResultKind.Void, null, null, "POST", new ServiceOperationParameter[] { parameter });
                return operation;
            }
            else if (type == typeof(ServiceOperationParameter))
            {
                return new ServiceOperationParameter("o", ResourceType.GetPrimitiveResourceType(typeof(string)));
            }
            else if (type == typeof(ResourceSet))
            {
                ResourceProperty p = new ResourceProperty("ID", ResourcePropertyKind.Primitive | ResourcePropertyKind.Key, ResourceType.GetPrimitiveResourceType(typeof(int)));

                ResourceType resourceType = new ResourceType(typeof(object), ResourceTypeKind.EntityType, null, "Foo", "NoBaseType", false);
                resourceType.AddProperty(p);
                return new ResourceSet("Customers", resourceType);
            }

            throw new Exception(String.Format("Unexpected type encountered: '{0}'", type.FullName));
        }
Example #2
0
        public void TestServiceOperationsWithSpatialParameters()
        {

            Action<string, Type, DSPMetadata> AddIdentityServiceOp = (name, type, dspMetadata) =>
            {
                var primitiveType = Microsoft.OData.Service.Providers.ResourceType.GetPrimitiveResourceType(type);
                var parameter = new ServiceOperationParameter("param1", primitiveType);
                dspMetadata.AddServiceOperation(name, ServiceOperationResultKind.DirectValue, primitiveType, null, "GET",
                                      new ServiceOperationParameter[] { parameter });
            };

            DSPUnitTestServiceDefinition roadTripServiceDefinition = GetRoadTripServiceDefinition(typeof(GeographyPoint), TestPoint.DefaultValues, false, false,
                (m) =>
                {
                    AddIdentityServiceOp("GetGeographyPoint", typeof(GeographyPoint), m);
                    AddIdentityServiceOp("GetGeometryPoint", typeof(GeometryPoint), m);
                    AddIdentityServiceOp("GetDouble", typeof(double), m);
                });


            Func<object[], object> sopCallBack = (args) =>
                                                     {
                                                         return args[0];
                                                     };
            roadTripServiceDefinition.CreateDataSource = (metadata) =>
                                                             {
                                                                 return new DSPContext()
                                                                            {
                                                                                ServiceOperations =
                                                                                    new Dictionary
                                                                                    <string, Func<object[], object>>()
                                                                                        {
                                                                                         {"GetGeographyPoint", sopCallBack},
                                                                                         {"GetGeometryPoint", sopCallBack},
                                                                                         {"GetDouble", sopCallBack},
                                                                                        }
                                                                            };
                                                             };

            using (TestWebRequest request = roadTripServiceDefinition.CreateForInProcess())
            {
                request.StartService();

                // GET
                request.Accept = "application/xml";
                request.RequestContentType = null;
                request.HttpMethod = "GET";
                request.RequestUriString = "/GetDouble?param1=1.2";
                request.SendRequest();
                var response = request.GetResponseStreamAsText();
                StringAssert.Contains(response, "1.2", "didn't get the identity back");

                const string wellKnownText = "SRID=4326;POINT (177.508 51.9917)";

                // GET
                request.Accept = "application/xml";

                request.RequestContentType = null;
                request.HttpMethod = "GET";
                request.RequestUriString = string.Format("/GetGeographyPoint?param1=geography'{0}'", wellKnownText);
                request.SendRequest();
                response = request.GetResponseStreamAsText();
                var geographyPoint = WellKnownTextSqlFormatter.Create().Read<Geography>(new StringReader(wellKnownText));
                string geographyPointReturn = GmlFormatter.Create().Write(geographyPoint);
                // The gml namespace is already declared on the top-level element
                geographyPointReturn = geographyPointReturn.Replace(" xmlns:gml=\"http://www.opengis.net/gml\"", string.Empty);
                StringAssert.Contains(response, geographyPointReturn, "didn't get the identity back");

                // GET
                request.Accept = "application/xml";
                request.RequestContentType = null;
                request.HttpMethod = "GET";
                request.RequestUriString = string.Format("/GetGeometryPoint?param1=geometry'{0}'", wellKnownText);
                request.SendRequest();
                response = request.GetResponseStreamAsText();
                var geometryPoint = WellKnownTextSqlFormatter.Create().Read<Geometry>(new StringReader(wellKnownText));
                string geometryPointReturn = GmlFormatter.Create().Write(geometryPoint);
                // The gml namespace is already declared on the top-level element
                geometryPointReturn = geometryPointReturn.Replace(" xmlns:gml=\"http://www.opengis.net/gml\"", string.Empty);
                StringAssert.Contains(response, geometryPointReturn, "didn't get the identity back");
            }
        }
        /// <summary>
        /// Returns a new <see cref="ServiceOperation"/> based on the specified <paramref name="method"/>
        /// instance.
        /// </summary>
        /// <param name="method">Method to expose as a service operation.</param>
        /// <param name="protocolMethod">Protocol (for example HTTP) method the service operation responds to.</param>
        /// <returns>Service operation corresponding to give <paramref name="method"/>.</returns>
        private ServiceOperation GetServiceOperationForMethod(MethodInfo method, string protocolMethod)
        {
            Debug.Assert(method != null, "method != null");
            Debug.Assert(!method.IsAbstract, "!method.IsAbstract - if method is abstract, the type is abstract - already checked");

            bool hasSingleResult = BaseServiceProvider.MethodHasSingleResult(method);
            ServiceOperationResultKind resultKind;
            ResourceType resourceType = null;

            if (method.ReturnType == typeof(void))
            {
                resultKind = ServiceOperationResultKind.Void;
            }
            else
            {
                // Load the metadata of the resource type on the fly.
                // For Edm provider, it might not mean anything, but for reflection service provider, we need to
                // load the metadata of the type if its used only in service operation case
                Type resultType;
                if (WebUtil.IsPrimitiveType(method.ReturnType))
                {
                    resultKind   = ServiceOperationResultKind.DirectValue;
                    resultType   = method.ReturnType;
                    resourceType = PrimitiveResourceTypeMap.TypeMap.GetPrimitive(resultType);
                }
                else
                {
                    Type queryableElement = BaseServiceProvider.GetIQueryableElement(method.ReturnType);
                    if (queryableElement != null)
                    {
                        resultKind = hasSingleResult ?
                                     ServiceOperationResultKind.QueryWithSingleResult :
                                     ServiceOperationResultKind.QueryWithMultipleResults;
                        resultType = queryableElement;
                    }
                    else
                    {
                        Type enumerableElement = BaseServiceProvider.GetIEnumerableElement(method.ReturnType);
                        if (enumerableElement != null)
                        {
                            resultKind = ServiceOperationResultKind.Enumeration;
                            resultType = enumerableElement;
                        }
                        else
                        {
                            resultType = method.ReturnType;
                            resultKind = ServiceOperationResultKind.DirectValue;
                        }
                    }

                    Debug.Assert(resultType != null, "resultType != null");
                    resourceType = PrimitiveResourceTypeMap.TypeMap.GetPrimitive(resultType);
                    if (resourceType == null)
                    {
                        resourceType = this.ResolveResourceType(resultType);
                    }
                }

                if (resourceType == null)
                {
                    throw new InvalidOperationException(Strings.BaseServiceProvider_UnsupportedReturnType(method, method.ReturnType));
                }

                if (resultKind == ServiceOperationResultKind.Enumeration && hasSingleResult)
                {
                    throw new InvalidOperationException(Strings.BaseServiceProvider_IEnumerableAlwaysMultiple(type, method));
                }
            }

            ParameterInfo[]             parametersInfo = method.GetParameters();
            ServiceOperationParameter[] parameters     = new ServiceOperationParameter[parametersInfo.Length];
            for (int i = 0; i < parameters.Length; i++)
            {
                ParameterInfo parameterInfo = parametersInfo[i];
                if (parameterInfo.IsOut || parameterInfo.IsRetval)
                {
                    throw new InvalidOperationException(Strings.BaseServiceProvider_ParameterNotIn(method, parameterInfo));
                }

                ResourceType parameterType = PrimitiveResourceTypeMap.TypeMap.GetPrimitive(parameterInfo.ParameterType);
                if (parameterType == null)
                {
                    throw new InvalidOperationException(
                              Strings.BaseServiceProvider_ParameterTypeNotSupported(method, parameterInfo, parameterInfo.ParameterType));
                }

                string parameterName = parameterInfo.Name ?? "p" + i.ToString(CultureInfo.InvariantCulture);
                parameters[i] = new ServiceOperationParameter(parameterName, parameterType);
            }

            ResourceSet resourceSet = null;

            if (resourceType != null && resourceType.ResourceTypeKind == ResourceTypeKind.EntityType)
            {
                resourceSet = this.ResolveResourceSet(resourceType, method);

                if (resourceSet == null)
                {
                    throw new InvalidOperationException(
                              Strings.BaseServiceProvider_ServiceOperationMissingSingleEntitySet(method, resourceType.FullName));
                }
            }

            ServiceOperation operation = new ServiceOperation(method.Name, resultKind, resourceType, resourceSet, protocolMethod, parameters);

            operation.CustomState = method;

            MimeTypeAttribute attribute = BaseServiceProvider.GetMimeTypeAttribute(method);

            if (attribute != null)
            {
                operation.MimeType = attribute.MimeType;
            }

            return(operation);
        }
        /// <summary>
        /// Returns a new <see cref="ServiceOperation"/> based on the specified <paramref name="method"/>
        /// instance.
        /// </summary>
        /// <param name="method">Method to expose as a service operation.</param>
        /// <param name="protocolMethod">Protocol (for example HTTP) method the service operation responds to.</param>
        /// <returns>Service operation corresponding to give <paramref name="method"/>.</returns>
        private ServiceOperation GetServiceOperationForMethod(MethodInfo method, string protocolMethod)
        {
            Debug.Assert(method != null, "method != null");
            Debug.Assert(!method.IsAbstract, "!method.IsAbstract - if method is abstract, the type is abstract - already checked");

            bool hasSingleResult = BaseServiceProvider.MethodHasSingleResult(method);
            ServiceOperationResultKind resultKind;
            ResourceType resourceType = null;
            if (method.ReturnType == typeof(void))
            {
                resultKind = ServiceOperationResultKind.Void;
            }
            else
            {
                // Load the metadata of the resource type on the fly.
                // For Edm provider, it might not mean anything, but for reflection service provider, we need to
                // load the metadata of the type if its used only in service operation case
                Type resultType;
                if (WebUtil.IsPrimitiveType(method.ReturnType))
                {
                    resultKind = ServiceOperationResultKind.DirectValue;
                    resultType = method.ReturnType;
                    resourceType = PrimitiveResourceTypeMap.TypeMap.GetPrimitive(resultType);
                }
                else
                {
                    Type queryableElement = BaseServiceProvider.GetIQueryableElement(method.ReturnType);
                    if (queryableElement != null)
                    {
                        resultKind = hasSingleResult ?
                            ServiceOperationResultKind.QueryWithSingleResult :
                            ServiceOperationResultKind.QueryWithMultipleResults;
                        resultType = queryableElement;
                    }
                    else
                    {
                        Type enumerableElement = BaseServiceProvider.GetIEnumerableElement(method.ReturnType);
                        if (enumerableElement != null)
                        {
                            resultKind = ServiceOperationResultKind.Enumeration;
                            resultType = enumerableElement;
                        }
                        else
                        {
                            resultType = method.ReturnType;
                            resultKind = ServiceOperationResultKind.DirectValue;
                        }
                    }

                    Debug.Assert(resultType != null, "resultType != null");
                    resourceType = PrimitiveResourceTypeMap.TypeMap.GetPrimitive(resultType);
                    if (resourceType == null)
                    {
                        resourceType = this.ResolveResourceType(resultType);
                    }
                }

                if (resourceType == null)
                {
                    throw new InvalidOperationException(Strings.BaseServiceProvider_UnsupportedReturnType(method, method.ReturnType));
                }

                if (resultKind == ServiceOperationResultKind.Enumeration && hasSingleResult)
                {
                    throw new InvalidOperationException(Strings.BaseServiceProvider_IEnumerableAlwaysMultiple(type, method));
                }
            }

            ParameterInfo[] parametersInfo = method.GetParameters();
            ServiceOperationParameter[] parameters = new ServiceOperationParameter[parametersInfo.Length];
            for (int i = 0; i < parameters.Length; i++)
            {
                ParameterInfo parameterInfo = parametersInfo[i];
                if (parameterInfo.IsOut || parameterInfo.IsRetval)
                {
                    throw new InvalidOperationException(Strings.BaseServiceProvider_ParameterNotIn(method, parameterInfo));
                }

                ResourceType parameterType = PrimitiveResourceTypeMap.TypeMap.GetPrimitive(parameterInfo.ParameterType);
                if (parameterType == null)
                {
                    throw new InvalidOperationException(
                        Strings.BaseServiceProvider_ParameterTypeNotSupported(method, parameterInfo, parameterInfo.ParameterType));
                }

                string parameterName = parameterInfo.Name ?? "p" + i.ToString(CultureInfo.InvariantCulture);
                parameters[i] = new ServiceOperationParameter(parameterName, parameterType);
            }

            ResourceSet resourceSet = null;
            if (resourceType != null && resourceType.ResourceTypeKind == ResourceTypeKind.EntityType)
            {
                resourceSet = this.ResolveResourceSet(resourceType, method);

                if (resourceSet == null)
                {
                    throw new InvalidOperationException(
                        Strings.BaseServiceProvider_ServiceOperationMissingSingleEntitySet(method, resourceType.FullName));
                }
            }

            ServiceOperation operation = new ServiceOperation(method.Name, resultKind, resourceType, resourceSet, protocolMethod, parameters);

            operation.CustomState = method;

            MimeTypeAttribute attribute = BaseServiceProvider.GetMimeTypeAttribute(method);
            if (attribute != null)
            {
                operation.MimeType = attribute.MimeType;
            }

            return operation;
        }