Skip to content

Commit 23baec8

Browse files
committed
Better deserialization using different CultureInfo, Unit tests fixed for non-english system culture
1 parent 4f26bd8 commit 23baec8

File tree

8 files changed

+64
-24
lines changed

8 files changed

+64
-24
lines changed

RestSharp.Tests/JsonTests.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,18 +120,19 @@ public void Can_Deserialize_Elements_to_Nullable_Values()
120120
[Fact]
121121
public void Can_Deserialize_Custom_Formatted_Date()
122122
{
123+
var culture = CultureInfo.InvariantCulture;
123124
var format = "dd yyyy MMM, hh:mm ss tt";
124125
var date = new DateTime(2010, 2, 8, 11, 11, 11);
125126

126127
var formatted = new
127128
{
128-
StartDate = date.ToString(format)
129+
StartDate = date.ToString(format, culture)
129130
};
130131

131132
var data = JsonConvert.SerializeObject(formatted);
132133
var response = new RestResponse { Content = data };
133134

134-
var json = new JsonDeserializer { DateFormat = format };
135+
var json = new JsonDeserializer { DateFormat = format, Culture = culture };
135136

136137
var output = json.Deserialize<PersonForJson>(response);
137138

RestSharp.Tests/SerializerTests.cs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
using System;
1818
using System.Collections.Generic;
19+
using System.Globalization;
1920
using System.Xml.Linq;
2021
using RestSharp.Serializers;
2122
using RestSharp.Tests.SampleClasses;
@@ -25,6 +26,12 @@ namespace RestSharp.Tests
2526
{
2627
public class SerializerTests
2728
{
29+
public SerializerTests()
30+
{
31+
System.Threading.Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
32+
System.Threading.Thread.CurrentThread.CurrentUICulture = CultureInfo.InstalledUICulture;
33+
}
34+
2835
[Fact]
2936
public void Serializes_Properties_In_Specified_Order() {
3037
var ordered = new OrderedProperties();
@@ -164,9 +171,9 @@ public void Can_serialize_a_list_which_is_the_root_element()
164171
}
165172
};
166173

167-
var xml = new XmlSerializer();
174+
var xml = new XmlSerializer();
168175
var doc = xml.Serialize(pocoList);
169-
var expected = GetPeopleXDoc();
176+
var expected = GetPeopleXDoc(CultureInfo.InvariantCulture);
170177

171178
Assert.Equal(expected.ToString(), doc);
172179
}
@@ -298,7 +305,7 @@ private XDocument GetSortedPropsXDoc() {
298305
return doc;
299306
}
300307

301-
private XDocument GetPeopleXDoc()
308+
private XDocument GetPeopleXDoc(CultureInfo culture)
302309
{
303310
var doc = new XDocument();
304311
var root = new XElement("People");
@@ -310,17 +317,17 @@ private XDocument GetPeopleXDoc()
310317
items.Add(new XElement("Item", new XElement("Name", "Three"), new XElement("Value", 3)));
311318
element.Add(new XElement("Name", "Foo"),
312319
new XElement("Age", 50),
313-
new XElement("Price", 19.95m),
314-
new XElement("StartDate", new DateTime(2009, 12, 18, 10, 2, 23).ToString()));
320+
new XElement("Price", 19.95m.ToString(culture)),
321+
new XElement("StartDate", new DateTime(2009, 12, 18, 10, 2, 23).ToString(culture)));
315322

316323
element.Add(items);
317324
root.Add(element);
318325
element = new XElement("Person");
319326

320327
element.Add(new XElement("Name", "Bar"),
321328
new XElement("Age", 23),
322-
new XElement("Price", 23.23m),
323-
new XElement("StartDate", new DateTime(2009, 12, 23, 10, 23, 23).ToString()));
329+
new XElement("Price", 23.23m.ToString(culture)),
330+
new XElement("StartDate", new DateTime(2009, 12, 23, 10, 23, 23).ToString(culture)));
324331

325332
element.Add(items);
326333

RestSharp.Tests/XmlTests.cs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#endregion
1616

1717
using System;
18+
using System.Globalization;
1819
using System.IO;
1920
using System.Linq;
2021
using System.Xml.Linq;
@@ -224,9 +225,10 @@ public void Can_Deserialize_Empty_Elements_to_Nullable_Values()
224225
[Fact]
225226
public void Can_Deserialize_Elements_to_Nullable_Values()
226227
{
227-
var doc = CreateXmlWithoutEmptyValues();
228+
var culture = CultureInfo.InvariantCulture;
229+
var doc = CreateXmlWithoutEmptyValues(culture);
228230

229-
var xml = new XmlDeserializer();
231+
var xml = new XmlDeserializer() {Culture = culture};
230232
var output = xml.Deserialize<NullableValues>(new RestResponse { Content = doc });
231233

232234
Assert.NotNull(output.Id);
@@ -241,20 +243,24 @@ public void Can_Deserialize_Elements_to_Nullable_Values()
241243
[Fact]
242244
public void Can_Deserialize_Custom_Formatted_Date()
243245
{
246+
var culture = CultureInfo.InvariantCulture;
244247
var format = "dd yyyy MMM, hh:mm ss tt zzz";
245248
var date = new DateTime(2010, 2, 8, 11, 11, 11);
246249

247250
var doc = new XDocument();
248251

249252
var root = new XElement("Person");
250-
root.Add(new XElement("StartDate", date.ToString(format)));
253+
root.Add(new XElement("StartDate", date.ToString(format, culture)));
251254

252255
doc.Add(root);
253256

254-
var xml = new XmlDeserializer();
255-
xml.DateFormat = format;
257+
var xml = new XmlDeserializer
258+
{
259+
DateFormat = format,
260+
Culture = culture
261+
};
256262

257-
var response = new RestResponse { Content = doc.ToString() };
263+
var response = new RestResponse { Content = doc.ToString() };
258264
var output = xml.Deserialize<PersonForXml>(response);
259265

260266
Assert.Equal(date, output.StartDate);
@@ -745,13 +751,13 @@ private static string CreateXmlWithNullValues()
745751
return doc.ToString();
746752
}
747753

748-
private static string CreateXmlWithoutEmptyValues()
754+
private static string CreateXmlWithoutEmptyValues(CultureInfo culture)
749755
{
750756
var doc = new XDocument();
751757
var root = new XElement("NullableValues");
752758

753759
root.Add(new XElement("Id", 123),
754-
new XElement("StartDate", new DateTime(2010, 2, 21, 9, 35, 00).ToString()),
760+
new XElement("StartDate", new DateTime(2010, 2, 21, 9, 35, 00).ToString(culture)),
755761
new XElement("UniqueId", new Guid(GuidString))
756762
);
757763

RestSharp/Deserializers/JsonDeserializer.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ private void Map(object x, JToken json)
110110
// no primitives can contain quotes so we can safely remove them
111111
// allows converting a json value like {"index": "1"} to an int
112112
var tmpVal = value.AsString().Replace("\"", string.Empty);
113-
prop.SetValue(x, tmpVal.ChangeType(type), null);
113+
prop.SetValue(x, tmpVal.ChangeType(type, Culture), null);
114114
}
115115
else if (type.IsEnum)
116116
{
@@ -153,7 +153,7 @@ private void Map(object x, JToken json)
153153
}
154154
else if (type == typeof(Decimal))
155155
{
156-
var dec = Decimal.Parse(value.AsString(), Culture);
156+
var dec = Decimal.Parse(value.AsString(Culture), Culture);
157157
prop.SetValue(x, dec, null);
158158
}
159159
else if (type == typeof(Guid))
@@ -259,7 +259,7 @@ private IList BuildList(Type type, JEnumerable<JToken> elements)
259259
var value = element as JValue;
260260
if (value != null)
261261
{
262-
list.Add(value.Value.ChangeType(itemType));
262+
list.Add(value.Value.ChangeType(itemType, Culture));
263263
}
264264
}
265265
else if (itemType == typeof(string))

RestSharp/Deserializers/XmlAttributeDeserializer.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ private void Map(object x, XElement root)
142142

143143
if (type.IsPrimitive)
144144
{
145-
prop.SetValue(x, value.ChangeType(type), null);
145+
prop.SetValue(x, value.ChangeType(type, Culture), null);
146146
}
147147
else if (type.IsEnum)
148148
{
@@ -166,14 +166,14 @@ private void Map(object x, XElement root)
166166
}
167167
else
168168
{
169-
value = DateTime.Parse(value.ToString());
169+
value = DateTime.Parse(value.ToString(), Culture);
170170
}
171171

172172
prop.SetValue(x, value, null);
173173
}
174174
else if (type == typeof(Decimal))
175175
{
176-
value = Decimal.Parse(value.ToString());
176+
value = Decimal.Parse(value.ToString(), Culture);
177177
prop.SetValue(x, value, null);
178178
}
179179
else if (type == typeof(Guid))

RestSharp/Deserializers/XmlDeserializer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ private void Map(object x, XElement root)
140140
}
141141
else if (type.IsPrimitive)
142142
{
143-
prop.SetValue(x, value.ChangeType(type), null);
143+
prop.SetValue(x, value.ChangeType(type, Culture), null);
144144
}
145145
else if (type.IsEnum)
146146
{

RestSharp/Extensions/MiscExtensions.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
// limitations under the License.
1515
#endregion
1616

17+
using System.Globalization;
1718
using System.IO;
1819
using Newtonsoft.Json.Linq;
1920
using System.Text;
@@ -82,6 +83,22 @@ public static string AsString(this JToken token)
8283
return token.Type == JTokenType.String ? token.Value<string>() : token.ToString();
8384
}
8485

86+
/// <summary>
87+
/// Gets string value from JToken
88+
/// </summary>
89+
/// <param name="token"></param>
90+
/// <returns></returns>
91+
public static string AsString(this JToken token, CultureInfo culture)
92+
{
93+
var value = token as JValue;
94+
if (value != null)
95+
{
96+
return (string)value.Value.ChangeType(typeof(string), culture);
97+
}
98+
99+
return token.Type == JTokenType.String ? token.Value<string>() : token.ToString();
100+
}
101+
85102
/// <summary>
86103
/// Converts a byte array to a string, using its byte order mark to convert it to the right encoding.
87104
/// http://www.shrinkrays.net/code-snippets/csharp/an-extension-method-for-converting-a-byte-array-to-a-string.aspx

RestSharp/Extensions/ReflectionExtensions.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,15 @@ public static object ChangeType(this object source, Type newType)
7272
#endif
7373
}
7474

75+
public static object ChangeType(this object source, Type newType, CultureInfo culture)
76+
{
77+
#if FRAMEWORK
78+
return Convert.ChangeType(source, newType, culture);
79+
#else
80+
return Convert.ChangeType(source, newType, null);
81+
#endif
82+
}
83+
7584
/// <summary>
7685
/// Find a value from a System.Enum by trying several possible variants
7786
/// of the string value of the enum.

0 commit comments

Comments
 (0)