/// <summary>
        /// This call is handled as synchronous, BUT it MUST be invoked on a thread separate from the main UI thread.
        /// Assumes that the OperationContract's parameters is exactly 1 params object[]. This is because there is no
        /// apparent way to send multiple different parameters in HTTP POST in Silverlight. Tuple cannot be serialized
        /// in Silverlight.
        ///
        /// Only handles HTTP POST requests (WebInvoke), not HTTP GET (WebGet). This is because WebGet only appears to accept
        /// string parameters.
        ///
        /// If I later come across an alternative way to pass multiple non-string parameters to a WCF service method,
        /// </summary>
        /// <typeparam name="TChannel"></typeparam>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="baseAddress"></param>
        /// <param name="methodcall"></param>
        /// <param name="returnType">user's desired return element Type, as either a single instance or in a collection. May not be what's declared on OperationContract (e.g. if return Type is object[])</param>
        /// <param name="parameters">currently required, but redundant since it's possible to get this information from the MethodCallExpression.Arguments</param>
        /// <returns></returns>
        public static object SynchronousCall <TChannel, TResult>(Uri baseAddress,
                                                                 Expression <Func <TChannel, TResult> > methodcall,
                                                                 Type returnType = null) //user's desired return Type, may not be what's declared on OperationContract (e.g. if return Type is object[])
        //,params object[] parameters)
        {
            object result                 = null;
            Stream stream                 = null;
            MethodCallExpression m        = (System.Linq.Expressions.MethodCallExpression)methodcall.Body;
            Type channelType              = m.Object.Type;//for debugging only
            IEnumerable <Type> knownTypes = GetServiceKnownTypes(channelType);

            if (returnType == null)
            {
                returnType = m.Method.ReturnType;
            }
            else
            {
                IEnumerable <Type> baseTypes = Resolver.GetBaseTypes(returnType);
                knownTypes = knownTypes.Union(baseTypes);
            }

            dynamic parameters = getArguments(m);

            string                     method;
            IOperationBehavior         webattribute;
            OperationContractAttribute operationcontract;
            WebMessageFormat           requestformat, responseformat;
            Uri endpoint = GetOperationInfo(m.Method, baseAddress, out method, out webattribute, out operationcontract, out requestformat, out responseformat);

            ManualResetEvent reset            = new ManualResetEvent(false);
            Action <Stream>  completedHandler = (s) =>
            {
                stream = s;
                if (returnType.IsArray || returnType.GetInterface("IEnumerable`1", false) != null)                //returnType == typeof(object[]))//)
                {
                    result = Deserialize(returnType, stream, responseformat);
                }
                else
                {
                    result = Deserialize(returnType, stream, responseformat);
                }
                reset.Set();
            };

            CreateHttpWebRequest(endpoint, instance: parameters,
                                 callback: completedHandler,
                                 method: method,
                                 requestFormat: requestformat,
                                 responseFormat: responseformat,
                                 knownTypes: knownTypes);
            reset.WaitOne();
            return(result);
        }
Exemple #2
0
        IQueryable IQueryProvider.CreateQuery(Expression expression)
        {
            Type elementType = Resolver.GetElementType(expression.Type);

            try
            {
                return((IQueryable)Activator.CreateInstance(typeof(Query <>).MakeGenericType(elementType), new object[] { this, expression }));
            }
            catch (TargetInvocationException tie)
            {
                throw tie.InnerException;
            }
        }
Exemple #3
0
        /// <summary>
        ///     Specifying the returnType is necessary because sometimes DataContractSerializer cannot deserialize the response
        ///     without knowing the exact Type of the response.
        ///     Sometimes DCS fails to deserialize, sometimes it doesn't, but the best practice is to always specify the expected
        ///     return Type.
        ///     If calling from SL, this call must be made from a thread separate from the main UI thread. For example,
        ///     enclose this call within a call to ThreadPool.QueueUserWorkItem.
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="methodcall">Lambda Expression that is the call to a method on the WebHttp service.</param>
        /// <param name="returnType">expected Type returned in the response</param>
        /// <returns></returns>
        //public object SynchronousCall<TResult>(Expression<Func<TChannel, TResult>> methodcall, Type returnType = null)
        public object SynchronousCall(Expression <Func <TChannel, object> > methodcall, Type returnType)
        {
            object result      = null;
            Stream stream      = null;
            var    m           = (MethodCallExpression)methodcall.Body;
            var    channelType = m.Object.Type;
            var    same        = returnType == m.Method.ReturnType;

            var baseTypes = Resolver.GetBaseTypes(returnType);

            foreach (var b in baseTypes)
            {
                _knownTypes.Add(b);
            }
            var parameters = GetParameters(m);

            string                     method;
            IOperationBehavior         webattribute;
            OperationContractAttribute operationcontract;
            WebMessageFormat           requestformat, responseformat;
            var endpoint = GetOperationInfo(m.Method, baseAddress, out method, out webattribute, out operationcontract,
                                            out requestformat, out responseformat);

            var             reset            = new ManualResetEvent(false);
            Action <Stream> completedHandler = s =>
            {
                stream = s;
                result = Deserialize(returnType, stream, responseformat);
                reset.Set();
            };

            CreateHttpWebRequest(endpoint, instance: parameters,
                                 callback: completedHandler,
                                 method: method,
                                 requestFormat: requestformat,
                                 responseFormat: responseformat);
            reset.WaitOne();
            return(result);
            //TChannel service = default(TChannel);
            //return methodcall.Compile().Invoke(service);
        }