forked from Code-Sharp/uHttpSharp
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathModelBinder.cs
More file actions
103 lines (86 loc) · 3.24 KB
/
Copy pathModelBinder.cs
File metadata and controls
103 lines (86 loc) · 3.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using uhttpsharp.Headers;
namespace uhttpsharp.ModelBinders
{
public class ModelBinder : IModelBinder
{
private readonly IObjectActivator _activator;
public ModelBinder(IObjectActivator activator)
{
_activator = activator;
}
public T Get<T>(byte[] raw, string prefix)
{
throw new NotSupportedException();
}
public T Get<T>(IHttpHeaders headers)
{
T retVal = _activator.Activate<T>(null);
foreach (PropertyInfo prop in retVal.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
if (prop.PropertyType.IsPrimitive || prop.PropertyType == typeof(string))
{
if (!headers.TryGetByName(prop.Name, out string stringValue)) continue;
object value = Convert.ChangeType(stringValue, prop.PropertyType);
prop.SetValue(retVal, value);
}
else
{
object value = Get(prop.PropertyType, headers, prop.Name);
prop.SetValue(retVal, value);
}
}
return retVal;
}
private object Get(Type type, IHttpHeaders headers, string prefix)
{
if (type.IsPrimitive || type == typeof(string))
{
return headers.TryGetByName(prefix, out string value) ? Convert.ChangeType(value, type) : null;
}
object retVal = _activator.Activate(type, null);
List<PropertyInfo> setValues =
retVal.GetType()
.GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(p => headers.TryGetByName($"{prefix}[{p.Name}]", out string _)).ToList();
if (setValues.Count == 0)
{
return null;
}
foreach (PropertyInfo prop in setValues)
{
if (!headers.TryGetByName($"{prefix}[{prop.Name}]", out string stringValue)) continue;
object value = prop.PropertyType.IsPrimitive || prop.PropertyType == typeof(string)
? Convert.ChangeType(stringValue, prop.PropertyType)
: Get(prop.PropertyType, headers, $"{prefix}[{prop.Name}]");
prop.SetValue(retVal, value);
}
return retVal;
}
public T Get<T>(IHttpHeaders headers, string prefix)
{
return (T)Get(typeof(T), headers, prefix);
}
}
public class ObjectActivator : IObjectActivator
{
public object Activate(Type type, Func<string, Type, object> argumentGetter)
{
return Activator.CreateInstance(type);
}
}
public interface IObjectActivator
{
object Activate(Type type, Func<string, Type, object> argumentGetter);
}
public static class ObjectActivatorExtensions
{
public static T Activate<T>(this IObjectActivator activator, Func<string, Type, object> argumentGetter)
{
return (T)activator.Activate(typeof(T), argumentGetter);
}
}
}