private static Expression BindArgument(Expression sourceExpression, ParameterModel parameter, string name) { var key = name ?? parameter.Name; var type = Nullable.GetUnderlyingType(parameter.ParameterType) ?? parameter.ParameterType; var valueArg = Expression.Convert( Expression.MakeIndex(sourceExpression, sourceExpression.Type.GetProperty("Item"), new[] { Expression.Constant(key) }), typeof(string)); MethodInfo parseMethod = (from m in type.GetMethods(BindingFlags.Public | BindingFlags.Static) let parameters = m.GetParameters() where m.Name == "Parse" && parameters.Length == 1 && parameters[0].ParameterType == typeof(string) select m).FirstOrDefault(); Expression expr = null; if (parseMethod != null) { expr = Expression.Call(parseMethod, valueArg); } else if (parameter.ParameterType != valueArg.Type) { // Convert.ChangeType() expr = Expression.Call(ChangeTypeMethodInfo, valueArg, Expression.Constant(type)); } else { expr = valueArg; } if (expr.Type != parameter.ParameterType) { expr = Expression.Convert(expr, parameter.ParameterType); } // property[key] == null ? default : (ParameterType){Type}.Parse(property[key]); expr = Expression.Condition( Expression.Equal(valueArg, Expression.Constant(null)), Expression.Default(parameter.ParameterType), expr); return(expr); }
private static Expression BindBody(Expression httpBody, ParameterModel parameter) { // Hard coded to JSON (and JSON.NET at that!) // Also this is synchronous, good luck generating async anything // new JsonSerializer().Deserialize( // new JsonTextReader( // new HttpRequestStreamReader( // context.Request.Body, Encoding.UTF8)), p.ParameterType); // var streamReaderCtor = typeof(HttpRequestStreamReader).GetConstructor(new[] { typeof(Stream), typeof(Encoding) }); var streamReader = Expression.New(streamReaderCtor, httpBody, Expression.Constant(Encoding.UTF8)); var textReaderCtor = typeof(JsonTextReader).GetConstructor(new[] { typeof(TextReader) }); var textReader = Expression.New(textReaderCtor, streamReader); Expression expr = Expression.Call(JsonDeserializeMethodInfo.MakeGenericMethod(parameter.ParameterType), textReader); return(expr); }