Skip to content

Commit c150402

Browse files
committed
Fixed a bug in the JsonDeserializer (Decimal type fields didn't properly deserialize when a system culture that doesn't use "." for decimal separator was present) and added some more tests
1 parent 40d2dce commit c150402

File tree

4 files changed

+77
-14
lines changed

4 files changed

+77
-14
lines changed

RestSharp.Tests/CultureChange.cs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using System;
2+
using System.Globalization;
3+
using System.Threading;
4+
5+
namespace RestSharp.Tests
6+
{
7+
public class CultureChange : IDisposable
8+
{
9+
public CultureInfo PreviousCulture { get; private set; }
10+
11+
public CultureChange(string culture)
12+
{
13+
if (culture == null)
14+
throw new ArgumentNullException("culture");
15+
16+
PreviousCulture = Thread.CurrentThread.CurrentCulture;
17+
18+
Thread.CurrentThread.CurrentCulture = new CultureInfo(culture);
19+
}
20+
21+
#region IDisposable Members
22+
23+
public void Dispose()
24+
{
25+
if (PreviousCulture != null)
26+
{
27+
Thread.CurrentThread.CurrentCulture = PreviousCulture;
28+
29+
PreviousCulture = null;
30+
}
31+
}
32+
33+
#endregion
34+
}
35+
}

RestSharp.Tests/JsonTests.cs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ namespace RestSharp.Tests
3030
{
3131
public class JsonTests
3232
{
33-
private const string GuidString = "AC1FC4BC-087A-4242-B8EE-C53EBE9887A5";
33+
private const string AlternativeCulture = "pt-PT";
34+
35+
private const string GuidString = "AC1FC4BC-087A-4242-B8EE-C53EBE9887A5";
3436

3537
[Fact]
3638
public void Can_Deserialize_4sq_Json_With_Root_Element_Specified()
@@ -233,6 +235,15 @@ public void Can_Deserialize_With_Default_Root()
233235
Assert.Equal("Foe 2", p.Foes["dict2"].Nickname);
234236
}
235237

238+
[Fact]
239+
public void Can_Deserialize_With_Default_Root_Alternative_Culture()
240+
{
241+
using (new CultureChange(AlternativeCulture))
242+
{
243+
Can_Deserialize_With_Default_Root();
244+
}
245+
}
246+
236247
[Fact]
237248
public void Can_Deserialize_Names_With_Underscores_With_Default_Root()
238249
{
@@ -262,6 +273,15 @@ public void Can_Deserialize_Names_With_Underscores_With_Default_Root()
262273
Assert.Equal("Foe 2", p.Foes["dict2"].Nickname);
263274
}
264275

276+
[Fact]
277+
public void Can_Deserialize_Names_With_Underscores_With_Default_Root_Alternative_Culture()
278+
{
279+
using (new CultureChange(AlternativeCulture))
280+
{
281+
Can_Deserialize_Names_With_Underscores_With_Default_Root();
282+
}
283+
}
284+
265285
[Fact]
266286
public void Can_Deserialize_Names_With_Dashes_With_Default_Root()
267287
{
@@ -291,6 +311,15 @@ public void Can_Deserialize_Names_With_Dashes_With_Default_Root()
291311
Assert.Equal("Foe 2", p.Foes["dict2"].Nickname);
292312
}
293313

314+
[Fact]
315+
public void Can_Deserialize_Names_With_Dashes_With_Default_Root_Alternative_Culture()
316+
{
317+
using (new CultureChange(AlternativeCulture))
318+
{
319+
Can_Deserialize_Names_With_Dashes_With_Default_Root();
320+
}
321+
}
322+
294323
[Fact]
295324
public void Ignore_Protected_Property_That_Exists_In_Data()
296325
{

RestSharp.Tests/RestSharp.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878
</Reference>
7979
</ItemGroup>
8080
<ItemGroup>
81+
<Compile Include="CultureChange.cs" />
8182
<Compile Include="JsonTests.cs" />
8283
<Compile Include="Fakes\NullHttp.cs" />
8384
<Compile Include="NamespacedXmlTests.cs" />

RestSharp/Deserializers/JsonDeserializer.cs

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ private void Map(object target, IDictionary<string, object> data)
7878

7979
if (value == null) continue;
8080

81+
var stringValue = Convert.ToString(value, Culture);
82+
8183
// check for nullable and extract underlying type
8284
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
8385
{
@@ -88,37 +90,34 @@ private void Map(object target, IDictionary<string, object> data)
8890
{
8991
// no primitives can contain quotes so we can safely remove them
9092
// allows converting a json value like {"index": "1"} to an int
91-
var tmpVal = value.ToString().Replace("\"", string.Empty);
93+
var tmpVal = stringValue.Replace("\"", string.Empty);
9294
prop.SetValue(target, tmpVal.ChangeType(type, Culture), null);
9395
}
9496
else if (type.IsEnum)
9597
{
96-
var converted = type.FindEnumValue(value.ToString(), Culture);
98+
var converted = type.FindEnumValue(stringValue, Culture);
9799
prop.SetValue(target, converted, null);
98100
}
99101
else if (type == typeof(Uri))
100102
{
101-
string raw = value.ToString();
102-
var uri = new Uri(raw, UriKind.RelativeOrAbsolute);
103+
var uri = new Uri(stringValue, UriKind.RelativeOrAbsolute);
103104
prop.SetValue(target, uri, null);
104105
}
105106
else if (type == typeof(string))
106107
{
107-
string raw = value.ToString();
108-
prop.SetValue(target, raw, null);
108+
prop.SetValue(target, stringValue, null);
109109
}
110110
else if (type == typeof(DateTime) || type == typeof(DateTimeOffset))
111111
{
112112
DateTime dt;
113-
var clean = value.ToString();
114113
if (DateFormat.HasValue())
115114
{
116-
dt = DateTime.ParseExact(clean, DateFormat, Culture);
115+
dt = DateTime.ParseExact(stringValue, DateFormat, Culture);
117116
}
118117
else
119118
{
120119
// try parsing instead
121-
dt = clean.ParseJsonDate(Culture);
120+
dt = stringValue.ParseJsonDate(Culture);
122121
}
123122

124123
if (type == typeof(DateTime))
@@ -132,18 +131,17 @@ private void Map(object target, IDictionary<string, object> data)
132131
}
133132
else if (type == typeof(Decimal))
134133
{
135-
var dec = Decimal.Parse(value.ToString(), Culture);
134+
var dec = Decimal.Parse(stringValue, Culture);
136135
prop.SetValue(target, dec, null);
137136
}
138137
else if (type == typeof(Guid))
139138
{
140-
string raw = value.ToString();
141-
var guid = string.IsNullOrEmpty(raw) ? Guid.Empty : new Guid(raw);
139+
var guid = string.IsNullOrEmpty(stringValue) ? Guid.Empty : new Guid(stringValue);
142140
prop.SetValue(target, guid, null);
143141
}
144142
else if (type == typeof(TimeSpan))
145143
{
146-
var timeSpan = TimeSpan.Parse(value.ToString());
144+
var timeSpan = TimeSpan.Parse(stringValue);
147145
prop.SetValue(target, timeSpan, null);
148146
}
149147
else if (type.IsGenericType)

0 commit comments

Comments
 (0)