static void SendJsonResponse(ServiceHandlerRequestContext context, object value) { var response = context.HttpContext.Response; response.ContentType = "application/json"; JsonSerializer serializer = new JsonSerializer(); #if DEBUG serializer.Formatting = Formatting.Indented; #endif var resolver = serializer.ContractResolver as DefaultContractResolver; if (context.ServiceConfig.JsonFormatMode == JsonFormatModes.CamelCase) { resolver.NamingStrategy = new CamelCaseNamingStrategy(); } using (var sw = new StreamWriter(response.Body)) { using (JsonWriter writer = new JsonTextWriter(sw)) { serializer.Serialize(writer, value); } } }
public async Task ProcessRequest() { var context = new ServiceHandlerRequestContext() { HttpContext = HttpContext, ServiceConfig = ServiceConfiguration, Url = new ServiceHandlerRequestContextUrl() { Url = UriHelper.GetDisplayUrl(HttpContext.Request), UrlPath = HttpContext.Request.Path.Value.ToString(), QueryString = HttpContext.Request.QueryString, HttpMethod = HttpContext.Request.Method.ToUpper() } }; try { if (context.ServiceConfig.HttpsMode == ControllerHttpsMode.RequireHttps && HttpContext.Request.Scheme != "https") { throw new UnauthorizedAccessException(Resources.ServiceMustBeAccessedOverHttps); } if (ServiceConfiguration.OnAfterMethodInvoke != null) { await ServiceConfiguration.OnBeforeMethodInvoke(context); } await ExecuteMethod(context); ServiceConfiguration.OnAfterMethodInvoke?.Invoke(context); if (string.IsNullOrEmpty(context.ResultJson)) { context.ResultJson = JsonSerializationUtils.Serialize(context.ResultValue); } SendJsonResponse(context, context.ResultValue); } catch (Exception ex) { var error = new ErrorResponse(ex); SendJsonResponse(context, error); } }
public async Task ExecuteMethod(ServiceHandlerRequestContext handlerContext) { var config = ServiceHandlerConfiguration.Current; var httpVerb = handlerContext.HttpContext.Request.Method; if (httpVerb == "OPTIONS" && config.Cors.UseCorsPolicy) { // emty response - ASP.NET will provide CORS headers via applied policy handlerContext.HttpContext.Response.StatusCode = StatusCodes.Status204NoContent; return; } // get the adjusted - methodname. var lowerPath = handlerContext.Url.UrlPath; if (!lowerPath.EndsWith("/")) { lowerPath += "/"; } var basePath = ServiceConfiguration.RouteBasePath; if (!basePath.EndsWith("/")) { basePath += "/"; } var path = lowerPath.Replace(basePath.ToLower(), ""); // split out the remaining path tokens var pathTokens = path.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); // try to figure out the method to invoke // first parameter or empty string method = string.Empty; var urlParameterTokens = pathTokens; if (pathTokens.Length > 0) { method = pathTokens[0]; urlParameterTokens = pathTokens.Skip(1).ToArray(); } // pick up the configured service implementation type and create an instance var serviceType = handlerContext.ServiceConfig.ServiceType; var inst = ReflectionUtils.CreateInstanceFromType(serviceType); if (inst == null) { throw new InvalidOperationException(string.Format(Resources.UnableToCreateTypeInstance, serviceType)); } // No explicitly defined contract interface found. Therefore, we try to use one implicitly var interfaces = serviceType.GetInterfaces(); if (interfaces.Length < 1) { throw new NotSupportedException(Resources.HostedServiceRequiresAnInterface); } // assume service interface is first interface var contractType = interfaces[0]; var methodToInvoke = GetMethodNameFromUrlFragmentAndContract(path, handlerContext.Url.HttpMethod, contractType); if (methodToInvoke == null) { methodToInvoke = GetMethodNameFromUrlFragmentAndContract(path, handlerContext.Url.HttpMethod, serviceType); if (methodToInvoke == null) { throw new InvalidOperationException(string.Format(Resources.ServiceMethodDoesntExist, method, handlerContext.Url.HttpMethod)); } } var parameterList = new object[] { }; object result = null; if (HttpContext.Request.ContentLength > 0) { // simplistic - no parameters or single body post parameter var paramInfos = methodToInvoke.GetParameters(); if (paramInfos.Length > 0) { var parm = paramInfos[0]; JsonSerializer serializer = new JsonSerializer(); using (var sw = new StreamReader(HttpContext.Request.Body)) { using (JsonReader reader = new JsonTextReader(sw)) { var parameterData = serializer.Deserialize(reader, parm.ParameterType); parameterList = new object[] { parameterData }; } } } } try { handlerContext.ResultValue = methodToInvoke.Invoke(inst, parameterList); } catch (Exception ex) { throw new InvalidOperationException(string.Format(Resources.UnableToExecuteMethod, methodToInvoke.Name, ex.Message)); } return; }