Skip to content

Commit f58594f

Browse files
committed
Switched to TypeDescriptor instead of classic reflection.
1 parent 2ff758a commit f58594f

File tree

11 files changed

+193
-284
lines changed

11 files changed

+193
-284
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ publish/
9797

9898
# NuGet Packages Directory
9999
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
100-
#packages/
100+
packages/
101101

102102
# Windows Azure Build Output
103103
csx

Mvc.Datatables/Mvc.Datatables.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@
132132
<Compile Include="Serialization\LegacyFilterRequestModelBinder.cs" />
133133
<Compile Include="Serialization\LegacyPageResponseConverter.cs" />
134134
<Compile Include="Serialization\PageResponseConverter.cs" />
135+
<Compile Include="Util\JsonConvertHelper.cs" />
135136
<Compile Include="Util\TransformTypeInfo.cs" />
136137
<Compile Include="Processing\TypeFilters.cs" />
137138
<Compile Include="Util\TypeExtensions.cs" />

Mvc.Datatables/Properties/AssemblyInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,5 @@
3030
//
3131
// You can specify all the values or you can default the Revision and Build Numbers
3232
// by using the '*' as shown below:
33-
[assembly: AssemblyVersion("1.0.0.1")]
34-
[assembly: AssemblyFileVersion("1.0.0.1")]
33+
[assembly: AssemblyVersion("1.0.0.2")]
34+
[assembly: AssemblyFileVersion("1.0.0.2")]

Mvc.Datatables/Reflection/DataTablesPropertyInfo.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1+
using Newtonsoft.Json;
12
using System;
2-
using System.Reflection;
3-
using Newtonsoft.Json.Serialization;
3+
using System.ComponentModel;
44

55
namespace Mvc.Datatables.Reflection
66
{
77
public class DataTablesPropertyInfo
88
{
9-
public PropertyInfo PropertyInfo { get; private set; }
10-
public JsonProperty JsonProperty { get; private set; }
9+
public PropertyDescriptor PropertyInfo { get; private set; }
10+
public JsonPropertyAttribute JsonProperty { get; private set; }
1111

1212
public Type Type
1313
{
@@ -19,7 +19,7 @@ public string Name
1919
get { return this.JsonProperty != null ? this.JsonProperty.PropertyName : this.PropertyInfo.Name; }
2020
}
2121

22-
public DataTablesPropertyInfo(PropertyInfo propertyInfo, JsonProperty jsonProperty)
22+
public DataTablesPropertyInfo(PropertyDescriptor propertyInfo, JsonPropertyAttribute jsonProperty)
2323
{
2424
this.PropertyInfo = propertyInfo;
2525
}

Mvc.Datatables/Reflection/DataTablesTypeInfo.cs

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,26 @@
1-
using System;
2-
using System.Collections.Concurrent;
1+
using Newtonsoft.Json;
2+
using System;
33
using System.Collections.Generic;
44
using System.Collections.Specialized;
5+
using System.ComponentModel;
56
using System.Linq;
6-
using System.Reflection;
7-
using Newtonsoft.Json;
8-
using Newtonsoft.Json.Serialization;
97

108
namespace Mvc.Datatables.Reflection
119
{
1210
public static class DataTablesTypeInfo
1311
{
14-
private static ConcurrentDictionary<Type, DataTablesPropertyInfo[]> _propertiesCache = new ConcurrentDictionary<Type, DataTablesPropertyInfo[]>();
15-
1612
public static DataTablesPropertyInfo[] Properties(Type type)
1713
{
18-
return _propertiesCache.GetOrAdd(type, t =>
19-
{
20-
var infos = from pi in t.GetProperties()
21-
where pi.GetCustomAttribute<JsonIgnoreAttribute>() == null
22-
let jsonProperty = (pi.GetCustomAttributes()).OfType<JsonProperty>().SingleOrDefault()
23-
select new DataTablesPropertyInfo(pi, jsonProperty);
24-
return infos.ToArray();
25-
});
14+
var typeDescriptor = TypeDescriptor.GetProvider(type).GetTypeDescriptor(type);
15+
if (typeDescriptor == null)
16+
return new DataTablesPropertyInfo[0];
17+
18+
var infos = from PropertyDescriptor pi in typeDescriptor.GetProperties()
19+
where pi.Attributes.Cast<Attribute>().OfType<JsonIgnoreAttribute>().Count() == 0
20+
let jsonProperty = pi.Attributes.Cast<Attribute>().OfType<JsonPropertyAttribute>().SingleOrDefault()
21+
select new DataTablesPropertyInfo(pi, jsonProperty);
22+
23+
return infos.ToArray();
2624
}
2725
}
2826

@@ -40,7 +38,7 @@ public static Dictionary<string, object> ToDictionary(T row)
4038
var dictionary = new Dictionary<string, object>();
4139

4240
foreach (var pi in Properties)
43-
dictionary[pi.Name] = pi.PropertyInfo.GetValue(row, null);
41+
dictionary[pi.Name] = pi.PropertyInfo.GetValue(row);
4442

4543
return dictionary;
4644
}
@@ -50,7 +48,7 @@ public static OrderedDictionary ToOrderedDictionary(T row)
5048
var dictionary = new OrderedDictionary();
5149

5250
foreach (var pi in Properties)
53-
dictionary[pi.Name] = pi.PropertyInfo.GetValue(row, null);
51+
dictionary[pi.Name] = pi.PropertyInfo.GetValue(row);
5452

5553
return dictionary;
5654
}

Mvc.Datatables/Serialization/FilterRequestConverter.cs

Lines changed: 2 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
using System;
55
using System.Collections.Generic;
66
using System.Linq;
7-
using System.Reflection;
87
using System.Text.RegularExpressions;
98

109
namespace Mvc.Datatables.Serialization
@@ -51,29 +50,7 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist
5150
otherProperties.Add(property.Name, property);
5251
}
5352

54-
foreach (Type type in objectType.GetInheritancHierarchy())
55-
{
56-
if (type == typeof(FilterRequest))
57-
break;
58-
59-
PropertyInfo[] propertiesInfos = type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
60-
foreach (PropertyInfo propertyInfo in propertiesInfos)
61-
{
62-
JsonIgnoreAttribute ignoreAttr = propertyInfo.GetCustomAttribute<JsonIgnoreAttribute>();
63-
if (ignoreAttr == null)
64-
{
65-
JsonPropertyAttribute propAttr = propertyInfo.GetCustomAttribute<JsonPropertyAttribute>();
66-
string propertyName = propAttr != null ? propAttr.PropertyName : propertyInfo.Name;
67-
68-
if (otherProperties.ContainsKey(propertyName))
69-
{
70-
object value = otherProperties[propertyName].Value.ToObject(propertyInfo.PropertyType,
71-
serializer);
72-
propertyInfo.SetValue(message, value);
73-
}
74-
}
75-
}
76-
}
53+
JsonConvertHelper.ReadJson(ref message, otherProperties, serializer, type => type == typeof(FilterRequest));
7754

7855
return message;
7956
}
@@ -195,26 +172,7 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s
195172
}
196173
}
197174

198-
foreach (Type type in value.GetType().GetInheritancHierarchy())
199-
{
200-
if (type == typeof(FilterRequest))
201-
break;
202-
203-
PropertyInfo[] properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
204-
foreach (PropertyInfo property in properties)
205-
{
206-
JsonIgnoreAttribute ignoreAttr = property.GetCustomAttribute<JsonIgnoreAttribute>();
207-
if (ignoreAttr == null)
208-
{
209-
JsonPropertyAttribute propAttr = property.GetCustomAttribute<JsonPropertyAttribute>();
210-
string propertyName = propAttr != null ? propAttr.PropertyName : property.Name;
211-
object propertyValue = property.GetValue(value);
212-
213-
writer.WritePropertyName(propertyName);
214-
serializer.Serialize(writer, propertyValue);
215-
}
216-
}
217-
}
175+
JsonConvertHelper.WriteJson(ref message, writer, serializer, type => type == typeof(FilterRequest));
218176

219177
writer.WriteEndObject();
220178
}

Mvc.Datatables/Serialization/FilterRequestModelBinder.cs

Lines changed: 90 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -14,99 +14,99 @@ public object BindModel(ControllerContext controllerContext, ModelBindingContext
1414
{
1515
FilterRequest message = new FilterRequest();
1616

17-
ReadConfiguration(ref message, controllerContext.HttpContext.Request.QueryString);
18-
ReadConfiguration(ref message, controllerContext.HttpContext.Request.Form);
17+
ReadConfiguration(ref message, controllerContext.HttpContext.Request.QueryString);
18+
ReadConfiguration(ref message, controllerContext.HttpContext.Request.Form);
1919

2020
return message;
2121
}
2222

23-
private void ReadConfiguration(ref FilterRequest message, NameValueCollection collection)
24-
{
25-
foreach (string key in collection.AllKeys)
26-
{
27-
if (key == "draw")
28-
message.Draw = GetValue<int>(collection[key]);
29-
30-
else if (key == "start")
31-
message.Start = GetValue<int>(collection[key]);
32-
33-
else if (key == "length")
34-
message.Length = GetValue<int>(collection[key]);
35-
36-
else if (key == "search[value]")
37-
message.Search.Value = GetValue<string>(collection[key]);
38-
39-
else if (key == "search[regex]")
40-
message.Search.IsRegex = GetValue<bool>(collection[key]);
41-
42-
else if (key.StartsWith("order"))
43-
ReadSortConfiguration(ref message, key, collection[key]);
44-
45-
else if (key.StartsWith("columns"))
46-
ReadColumnConfiguration(ref message, key, collection[key]);
47-
}
48-
}
49-
50-
private void ReadSortConfiguration(ref FilterRequest message, string key, object value)
51-
{
52-
Match match = Regex.Match(key, @"order\[([0-9]+)\](.+)");
53-
if (match.Success && match.Groups.Count == 3)
54-
{
55-
int index = Convert.ToInt32(match.Groups[1].Value);
56-
string propertyName = match.Groups[2].Value;
57-
58-
while (index >= message.Sort.Count)
59-
message.Sort.Add(new Sort());
60-
61-
if (propertyName == "[column]")
62-
message.Sort[index].Column = GetValue<int>(value);
63-
64-
else if (propertyName == "[dir]")
65-
message.Sort[index].Direction = GetValue<string>(value).AsSortDirection();
66-
}
67-
}
68-
69-
private void ReadColumnConfiguration(ref FilterRequest message, string key, object value)
70-
{
71-
Match match = Regex.Match(key, @"columns\[([0-9]+)\](.+)");
72-
if (match.Success && match.Groups.Count == 3)
73-
{
74-
int index = Convert.ToInt32(match.Groups[1].Value);
75-
string propertyName = match.Groups[2].Value;
76-
77-
Column currentColumn = null;
78-
79-
if (!message.HasColumn(index))
80-
{
81-
currentColumn = new Column();
82-
message.Columns.Add(index, currentColumn);
83-
}
84-
else
85-
currentColumn = message.GetColumn(index);
86-
87-
if (propertyName == "[data]")
88-
currentColumn.Data = GetValue<string>(value);
89-
90-
else if (propertyName == "[name]")
91-
currentColumn.Name = GetValue<string>(value);
92-
93-
else if (propertyName == "[searchable]")
94-
currentColumn.Searchable = GetValue<bool>(value);
95-
96-
else if (propertyName == "[orderable]")
97-
currentColumn.Sortable = GetValue<bool>(value);
98-
99-
else if (propertyName == "[search][value]")
100-
currentColumn.Search.Value = GetValue<string>(value);
101-
102-
else if (propertyName == "[search][regex]")
103-
currentColumn.Search.IsRegex = GetValue<bool>(value);
104-
}
105-
}
106-
107-
private static T GetValue<T>(object value)
108-
{
109-
return (value == null) ? default(T) : (T)Convert.ChangeType(value, typeof(T));
110-
}
23+
private void ReadConfiguration(ref FilterRequest message, NameValueCollection collection)
24+
{
25+
foreach (string key in collection.AllKeys)
26+
{
27+
if (key == "draw")
28+
message.Draw = GetValue<int>(collection[key]);
29+
30+
else if (key == "start")
31+
message.Start = GetValue<int>(collection[key]);
32+
33+
else if (key == "length")
34+
message.Length = GetValue<int>(collection[key]);
35+
36+
else if (key == "search[value]")
37+
message.Search.Value = GetValue<string>(collection[key]);
38+
39+
else if (key == "search[regex]")
40+
message.Search.IsRegex = GetValue<bool>(collection[key]);
41+
42+
else if (key.StartsWith("order"))
43+
ReadSortConfiguration(ref message, key, collection[key]);
44+
45+
else if (key.StartsWith("columns"))
46+
ReadColumnConfiguration(ref message, key, collection[key]);
47+
}
48+
}
49+
50+
private void ReadSortConfiguration(ref FilterRequest message, string key, object value)
51+
{
52+
Match match = Regex.Match(key, @"order\[([0-9]+)\](.+)");
53+
if (match.Success && match.Groups.Count == 3)
54+
{
55+
int index = Convert.ToInt32(match.Groups[1].Value);
56+
string propertyName = match.Groups[2].Value;
57+
58+
while (index >= message.Sort.Count)
59+
message.Sort.Add(new Sort());
60+
61+
if (propertyName == "[column]")
62+
message.Sort[index].Column = GetValue<int>(value);
63+
64+
else if (propertyName == "[dir]")
65+
message.Sort[index].Direction = GetValue<string>(value).AsSortDirection();
66+
}
67+
}
68+
69+
private void ReadColumnConfiguration(ref FilterRequest message, string key, object value)
70+
{
71+
Match match = Regex.Match(key, @"columns\[([0-9]+)\](.+)");
72+
if (match.Success && match.Groups.Count == 3)
73+
{
74+
int index = Convert.ToInt32(match.Groups[1].Value);
75+
string propertyName = match.Groups[2].Value;
76+
77+
Column currentColumn = null;
78+
79+
if (!message.HasColumn(index))
80+
{
81+
currentColumn = new Column();
82+
message.Columns.Add(index, currentColumn);
83+
}
84+
else
85+
currentColumn = message.GetColumn(index);
86+
87+
if (propertyName == "[data]")
88+
currentColumn.Data = GetValue<string>(value);
89+
90+
else if (propertyName == "[name]")
91+
currentColumn.Name = GetValue<string>(value);
92+
93+
else if (propertyName == "[searchable]")
94+
currentColumn.Searchable = GetValue<bool>(value);
95+
96+
else if (propertyName == "[orderable]")
97+
currentColumn.Sortable = GetValue<bool>(value);
98+
99+
else if (propertyName == "[search][value]")
100+
currentColumn.Search.Value = GetValue<string>(value);
101+
102+
else if (propertyName == "[search][regex]")
103+
currentColumn.Search.IsRegex = GetValue<bool>(value);
104+
}
105+
}
106+
107+
private static T GetValue<T>(object value)
108+
{
109+
return (value == null) ? default(T) : (T)Convert.ChangeType(value, typeof(T));
110+
}
111111
}
112112
}

0 commit comments

Comments
 (0)