public object[] ExtractParamsFromRequest(HttpRequest request) { var paramInfos = MethodInfo.GetParameters(); var queryValues = GetQueryString(request); var paramValues = paramInfos.Select(pi => { if (pi.GetCustomAttribute <FromBodyAttribute>() != null) { return(ContentHelper.DeserializeBodyFromRequest(pi.ParameterType, request)); } if (IsPrimitive(pi.ParameterType)) { return(ParseParamFromQuery(pi.ParameterType, queryValues.Get(pi.Name.ToLower()) ?? "")); } else { var instance = Activator.CreateInstance(pi.ParameterType); var instanceProps = instance.GetType().GetProperties(); foreach (var prop in instanceProps) { var s = queryValues[prop.Name.ToLower()]; if (s == null) { continue; } prop.SetValue(instance, ParseParamFromQuery(prop.PropertyType, s)); } return(instance); } }).ToArray(); return(paramValues); }
/// <summary> /// Use a service implementation as a web api endpoint /// </summary> /// <typeparam name="TService"></typeparam> /// <param name="appBuilder"></param> /// <param name="root">Not required. Root path for service endoint</param> /// <returns></returns> public static IApplicationBuilder UseWebApiEndpoint <TService>(this IApplicationBuilder appBuilder, string root = null) { var descriptors = MethodDescriptor.GetAll(typeof(TService), root); foreach (var descriptor in descriptors) { appBuilder.Use(async(context, next) => { if (!descriptor.IsRouteMatch(context.Request.Path.Value)) { await next(); return; } var descriptorHttpMethod = descriptor.HttpMethod.ToLower(); var requestHttpMethod = context.Request.Method.ToLower(); if (descriptorHttpMethod != requestHttpMethod) { await next(); return; } var contentType = ContentHelper.GetContentType(context.Request.ContentType); if (string.IsNullOrEmpty(contentType)) { context.Response.StatusCode = StatusCodes.Status400BadRequest; var info = new ExceptionInfo(new ArgumentException($"Http request must contain a 'Content-Type' header '{ContentTypes.Xml}' or '{ContentTypes.Json}'")); await context.Response.WriteAsync(ContentHelper.SerializeBody(info, ContentTypes.Json)); return; } try { var instance = (TService)appBuilder.ApplicationServices.GetService(typeof(TService)); var instanceMtd = instance.GetType().GetMethods().First(m => { if (m.Name != descriptor.MethodName) { return(false); } var methodParams = m.GetParameters(); var interfaceParams = descriptor.MethodInfo.GetParameters(); if (methodParams.Length != interfaceParams.Length) { return(false); } for (int n = 0; n < methodParams.Length; n++) { if (methodParams[n].ParameterType != interfaceParams[n].ParameterType) { return(false); } } return(true); }); var mtdParams = descriptor.ExtractParamsFromRequest(context.Request); var result = instanceMtd.Invoke(instance, mtdParams); context.Response.ContentType = contentType; context.Response.StatusCode = StatusCodes.Status200OK; if (instanceMtd.ReturnType.Name != "Void") { var text = ContentHelper.SerializeBody(result, contentType); await context.Response.WriteAsync(text); } } catch (Exception ex) { context.Response.StatusCode = StatusCodes.Status500InternalServerError; var info = new ExceptionInfo(ex); await context.Response.WriteAsync(info.ToJsonString()); } }); } return(appBuilder); }