Ejemplo n.º 1
0
        protected virtual object OnError(Exception e, IDictionary request)
        {
            if (JsonRpcTrace.Switch.TraceError)
            {
                JsonRpcTrace.Error(e);
            }

            return(JsonRpcError.FromException(e, LocalExecution));
        }
Ejemplo n.º 2
0
        /* TODO: Add async processing.
         *
         *  IAsyncResult BeginProcess(JsonReader input, JsonWriter output, AsyncCallback callback, object asyncState);
         *  void BeginProcess(IAsyncResult asyncResult); */

        public virtual IDictionary Invoke(IDictionary request)
        {
            if (request == null)
            {
                throw new ArgumentNullException();
            }

            //
            // Get the ID of the request.
            //

            object id = request["id"];

            //
            // If the ID is not there or was not set then this is a notification
            // request from the client that does not expect any response. Right
            // now, we don't support this.
            //

            bool isNotification = JsonNull.LogicallyEquals(id);

            if (isNotification)
            {
                throw new NotSupportedException("Notification are not yet supported.");
            }

            if (JsonRpcTrace.TraceInfo)
            {
                JsonRpcTrace.Info("Received request with the ID {0}.", id.ToString());
            }

            //
            // Get the method name and arguments.
            //

            string methodName = Mask.NullString((string)request["method"]);

            if (methodName.Length == 0)
            {
                throw new JsonRpcException("No method name supplied for this request.");
            }

            if (JsonRpcTrace.Switch.TraceInfo)
            {
                JsonRpcTrace.Info("Invoking method {1} on service {0}.", ServiceName, methodName);
            }

            //
            // Invoke the method on the service and handle errors.
            //

            object error  = null;
            object result = null;

            try
            {
                IService service = Service;
                Method   method  = service.GetClass().GetMethodByName(methodName);

                if (RequireIdempotency && !method.Idempotent)
                {
                    throw new JsonRpcException(string.Format("Method {1} on service {0} is not allowed for idempotent type of requests.", ServiceName, methodName));
                }

                object[] args;
                string[] names = null;

                object      argsObject = request["params"];
                IDictionary argByName  = argsObject as IDictionary;

                if (argByName != null)
                {
                    names = new string[argByName.Count];
                    argByName.Keys.CopyTo(names, 0);
                    args = new object[argByName.Count];
                    argByName.Values.CopyTo(args, 0);
                }
                else
                {
                    args = CollectionHelper.ToArray((ICollection)argsObject);
                }

                result = method.Invoke(service, names, args);
            }
            catch (MethodNotFoundException e)
            {
                error = OnError(e, request);
            }
            catch (InvocationException e)
            {
                error = OnError(e, request);
            }
            catch (TargetMethodException e)
            {
                error = OnError(e.InnerException, request);
            }
            catch (Exception e)
            {
                if (JsonRpcTrace.Switch.TraceError)
                {
                    JsonRpcTrace.Error(e);
                }

                throw;
            }

            //
            // Setup and return the response object.
            //

            return(CreateResponse(request, result, error));
        }