-
Notifications
You must be signed in to change notification settings - Fork 98
Expand file tree
/
Copy pathModelBinder.cs
More file actions
120 lines (97 loc) · 3.46 KB
/
ModelBinder.cs
File metadata and controls
120 lines (97 loc) · 3.46 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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
using System;
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)
{
var retVal = _activator.Activate<T>(null);
foreach (var prop in retVal.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
if (prop.PropertyType.IsPrimitive || prop.PropertyType == typeof(string))
{
string stringValue;
if (headers.TryGetByName(prop.Name, out stringValue))
{
var value = Convert.ChangeType(stringValue, prop.PropertyType);
prop.SetValue(retVal, value);
}
}
else
{
var 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))
{
string value;
if (headers.TryGetByName(prefix, out value))
{
return Convert.ChangeType(value, type);
}
return null;
}
var retVal = _activator.Activate(type, null);
string val;
var settedValues =
retVal.GetType()
.GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(p => headers.TryGetByName(prefix + "[" + p.Name + "]", out val)).ToList();
if (settedValues.Count == 0)
{
return null;
}
foreach (var prop in settedValues)
{
string stringValue;
if (headers.TryGetByName(prefix + "[" + prop.Name + "]", out stringValue))
{
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);
}
}
}