public void CompileInputParameters() { var explodedRoute = Route.Split('/'); var routeParams = explodedRoute.Where((section) => section.StartsWith("{") && section.EndsWith("}")).ToList(); var routeParamNames = routeParams.Select(section => section.Replace("}", "").Replace("{", "").ToLower()).ToList(); var compiled = new List <ExposedRestServerActionCompiledParameters>(); var properties = new List <PropertyInfo>(InputType?.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(prop => prop.CanWrite) ?? new PropertyInfo[0]); for (int i = 0; i < routeParams.Count; i++) { var routeParam = routeParams[i]; var routeParamName = routeParamNames[i]; var cparam = new ExposedRestServerActionCompiledParameters(); cparam.RouteIndex = Array.IndexOf(explodedRoute, routeParam); cparam.Param = routeParam; var property = properties.FirstOrDefault(prop => prop.Name.ToLower() == routeParamName); if (property == null) { throw new InvalidOperationException("Route parameter " + routeParam + " defined but no parameter found on " + (InputType?.Name ?? "NO INPUT TYPE!") + ". Route='" + Route + "'"); } cparam.Setter = property.SetMethod; cparam.Property = property; cparam.Type = property.PropertyType; var typeCode = Type.GetTypeCode(cparam.Type); if (typeCode == TypeCode.Object) { throw new InvalidOperationException("Route parameter " + routeParam + " defined but no primitive type. Route='" + Route + "'"); } compiled.Add(cparam); } List <string> regexRoute = new List <string>(); for (int i = 0; i < explodedRoute.Length; i++) { var routeToken = explodedRoute[i]; var cparam = compiled.FirstOrDefault(p => p.Param == routeToken); var token = Regex.Escape(routeToken); if (cparam != null) { token = "[^/]*"; } regexRoute.Add(token); } RouteRegex = new Regex("^" + string.Join("/", regexRoute) + "$", RegexOptions.Compiled); CompiledParameters = compiled.ToArray(); }
private static object MakeDestinationType(Type type, string value, string route, ExposedRestServerActionCompiledParameters param) { try { return(Convert.ChangeType(value, type)); } catch (Exception ex) { throw new FormatException("Unable to convert " + param.Param + " '" + (value ?? "NULL") + "' to destination type " + param.Type.Name + " on Route '" + route + "'", ex); } }
public async Task <bool> HandleRouteAsync(System.Net.Http.HttpListenerContext context) { string correlationId = Guid.NewGuid().ToString(); string route = MakeRoute(StripPort(context.Request.Url.AbsolutePath)); var restServerAction = GetActionForRoute(route); if (restServerAction == null) { return(false); } _logger.Info($"Handling route {route} - Correlation: {correlationId}"); object[] inputParameter = null; try { if (restServerAction.InputType != null) { string requestString = await context.Request.ReadContentAsStringAsync(); if (restServerAction.IsBodyRequested && restServerAction.IsParameterized) { inputParameter = new object[2] { null, requestString } } ; else { inputParameter = new object[1]; } if (!string.IsNullOrEmpty(requestString)) { if (restServerAction.InputType == typeof(string)) { inputParameter[0] = requestString; } else if (!restServerAction.IsBodyRequested) { inputParameter[0] = JsonConvert.DeserializeObject(requestString, restServerAction.InputType); } } if (restServerAction.IsParameterized) { if (inputParameter[0] == null) { inputParameter[0] = Activator.CreateInstance(restServerAction.InputType); } ExposedRestServerActionCompiledParameters.FillParameters(inputParameter[0], route, restServerAction.CompiledParameters); } } } catch (FormatException ex) // <-- CHANGE EXCEPTION TYPE!!!!1!11 { _logger.Info($"{correlationId} Routing failed, Bad Request."); context.Response.ReasonPhrase = "Bad Request - " + ex.Message; context.Response.StatusCode = 400; context.Response.Close(); return(true); } catch (JsonException ex) { _logger.Info($"{correlationId} Routing failed, Bad Request."); context.Response.ReasonPhrase = "Bad Request - " + ex.Message; context.Response.StatusCode = 400; context.Response.Close(); return(true); } object result = null; // make json response. context.Response.Headers.ContentType.Clear(); context.Response.Headers.ContentType.Add("application/json"); try { result = await restServerAction.Execute(context, inputParameter); } catch (Exception ex) { _logger.Info($"{correlationId} Routing failed, {route} action failed. Message: {ex.Message}"); context.Response.InternalServerError(); context.Response.Close(); return(true); } if (result != null) { try { string json = JsonConvert.SerializeObject(result); await context.Response.WriteContentAsync(json); } catch (JsonException ex) { _logger.Info($"{correlationId} Routing failed, {route} result serialization failed Type={result?.GetType().FullName ?? "NULL"}. Message: {ex.Message}"); context.Response.InternalServerError(); context.Response.Close(); return(true); } } _logger.Info($"{correlationId} Routing ended gracefully. {route}"); return(true); }