void IHttpHandler.ProcessRequest(HttpContext context) { context.Response.Cache.SetCacheability(HttpCacheability.Private); JsonRequest request = null; JsonResponse response = new JsonResponse(); try { if (this.error != null) { throw this.error; } Settings.OnInit(this.Service, context); if ("GET".Equals(context.Request.HttpMethod, StringComparison.OrdinalIgnoreCase)) { if (!Settings.AllowGetMethod) { throw new InvalidRequestException("GET HTTP method not allowed."); } request = this.BuildRequestFromGet(context); } else { request = this.BuildRequestFromPost(context); } if (request == null) { throw new InvalidRequestException("The JSON-RPC Request was empty."); } Settings.OnPreExecute(this.Service, context, request, response); this.HandleRequest(context, request, ref response); Settings.OnPostExecute(this.Service, context, request, response); } catch (InvalidRequestException ex) { context.Response.ClearContent(); response.Result = null; response.Error = new JsonError(ex, JsonRpcErrors.InvalidRequest); Settings.OnError(this.Service, context, request, response, ex); } catch (InvalidMethodException ex) { context.Response.ClearContent(); response.Result = null; response.Error = new JsonError(ex, JsonRpcErrors.MethodNotFound); Settings.OnError(this.Service, context, request, response, ex); } catch (InvalidParamsException ex) { context.Response.ClearContent(); response.Result = null; response.Error = new JsonError(ex, JsonRpcErrors.InvalidParams); Settings.OnError(this.Service, context, request, response, ex); } catch (JsonTypeCoercionException ex) { context.Response.ClearContent(); response.Result = null; response.Error = new JsonError(ex, JsonRpcErrors.InvalidParams); Settings.OnError(this.Service, context, request, response, ex); } catch (JsonDeserializationException ex) { context.Response.ClearContent(); response.Result = null; response.Error = new JsonError(ex, JsonRpcErrors.ParseError); Settings.OnError(this.Service, context, request, response, ex); } catch (JsonServiceException ex) { context.Response.ClearContent(); response.Result = null; response.Error = new JsonError(ex.InnerException??ex, JsonRpcErrors.InternalError); Settings.OnError(this.Service, context, request, response, ex); } catch (Exception ex) { context.Response.ClearContent(); response.Result = null; response.Error = new JsonError(ex, JsonRpcErrors.InternalError); Settings.OnError(this.Service, context, request, response, ex); } finally { try { Settings.Serialize(context.Response.Output, response); } catch (Exception ex) { if (ex is TargetInvocationException && ex.InnerException != null) { ex = ex.InnerException; } context.Response.ClearContent(); response.Result = null; response.Error = new JsonError(ex, JsonRpcErrors.InternalError); Settings.OnError(this.Service, context, request, response, ex); Settings.Serialize(context.Response.Output, response); } } Settings.OnUnload(this.Service, context); }
private void HandleRequest(HttpContext context, JsonRequest request, ref JsonResponse response) { context.Response.Clear(); HttpBrowserCapabilities browser = context.Request.Browser; // this is a specific fix for Opera 8.x // Opera 8 requires "text/plain" or "text/html" // otherwise the content encoding is mangled bool isOpera8 = browser.IsBrowser("opera") && (browser.MajorVersion <= 8); context.Response.ContentType = (isOpera8) ? MediaTypeNames.Text.Plain : JsonWriter.JsonMimeType; context.Response.ContentEncoding = System.Text.Encoding.UTF8; context.Response.AddHeader("Content-Disposition", "inline;filename=JsonResponse"+JsonServiceHandler.JsonFileExtension); response.ID = request.ID; System.Reflection.MethodInfo method = this.ServiceInfo.ResolveMethodName(request.Method); if (JsonServiceHandler.DescriptionMethodName.Equals(request.Method, StringComparison.Ordinal)) { response.Result = new JsonServiceDescription(this.ServiceInfo.ServiceType, this.serviceUrl); } else if (method != null) { Object[] positionalParams = null; if (request.NamedParams != null) { String[] paramMap = this.ServiceInfo.GetMethodParams(method.Name); positionalParams = new Object[paramMap.Length]; for (int i=0; i<paramMap.Length; i++) { // initially map name to position positionalParams[i] = request.NamedParams[paramMap[i]]; if (positionalParams[i] == null) { // try to get as named positional param positionalParams[i] = request.NamedParams[i.ToString()]; } } } else if (request.PositionalParams != null) { positionalParams = new object[request.PositionalParams.Length]; request.PositionalParams.CopyTo(positionalParams, 0); } try { if (positionalParams != null) { ParameterInfo[] paramInfo = method.GetParameters(); for (int i=0; i<positionalParams.Length; i++) { // ensure type compatibility of parameters positionalParams[i] = JsonReader.CoerceType(paramInfo[i].ParameterType, positionalParams[i]); } } response.Result = method.Invoke(this.Service, positionalParams); } catch (TargetParameterCountException ex) { throw new InvalidParamsException( String.Format( "Method \"{0}\" expects {1} parameters, {2} provided", method.Name, method.GetParameters().Length, positionalParams.Length), ex); } catch (TargetInvocationException ex) { throw new JsonServiceException((ex.InnerException??ex).Message, ex.InnerException??ex); } catch (Exception ex) { throw new JsonServiceException(ex.Message, ex); } } else { throw new InvalidMethodException("Invalid method name: "+request.Method); } }
/// <summary> /// Ctor /// </summary> /// <param name="context"></param> /// <param name="request"></param> /// <param name="response"></param> /// <param name="exception"></param> internal JrpcErrorEventArgs(HttpContext context, JsonRequest request, JsonResponse response, Exception exception) : base(context, request, response) { this.exception = exception; }
internal static void OnPreExecute(object sender, HttpContext context, JsonRequest request, JsonResponse response) { if (Settings.PreExecute != null) { Settings.PreExecute(sender, new JrpcEventArgs(context, request, response)); } }
internal static void OnError(object sender, HttpContext context, JsonRequest request, JsonResponse response, Exception exception) { if (Settings.Error != null) { try { Settings.Error(sender, new JrpcErrorEventArgs(context, request, response, exception)); } catch { // don't allow error handler to generate additional errors or messages break down } } }
/// <summary> /// Serializes an outgoing JSON-RPC response object /// </summary> /// <param name="output"></param> /// <param name="response"></param> public static void SerializeJsonRpc(TextWriter output, JsonResponse response) { using (JsonWriter writer = new JsonWriter(output)) { writer.Write(response); } }
/// <summary> /// Ctor /// </summary> /// <param name="context"></param> /// <param name="request"></param> /// <param name="response"></param> internal JrpcEventArgs(HttpContext context, JsonRequest request, JsonResponse response) : base(context) { this.request = request; this.response = response; }