Skip to content
This repository was archived by the owner on Dec 24, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/ServiceStack.Text/JsConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Threading;
using ServiceStack.Text.Common;
using ServiceStack.Text.Json;
Expand Down Expand Up @@ -815,6 +816,12 @@ internal static void AddUniqueType(Type type)

public class JsConfig<T>
{
static JsConfig()
{
// Run the type's static constructor (which may set OnDeserialized, etc.) before we cache any information about it
RuntimeHelpers.RunClassConstructor(typeof(T).TypeHandle);
}

/// <summary>
/// Always emit type info for this type. Takes precedence over ExcludeTypeInfo
/// </summary>
Expand Down
12 changes: 6 additions & 6 deletions tests/ServiceStack.Text.Tests/AdhocModelTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -780,20 +780,20 @@ public void Can_serialize_ICollection()
[Test]
public void Can_parse_different_3_part_date_formats()
{
Assert.That("28/06/2015".FromJsv<DateTime>().ToLongDateString(),
Is.EqualTo("Sunday, June 28, 2015"));
Assert.That("28/06/2015".FromJsv<DateTime>(),
Is.EqualTo(new DateTime(2015, 6, 28)));

Assert.That("6/28/2015".FromJsv<DateTime>().ToLongDateString(),
Is.EqualTo("Sunday, June 28, 2015"));
Assert.That("6/28/2015".FromJsv<DateTime>(),
Is.EqualTo(new DateTime(2015, 6, 28)));

DateTimeSerializer.OnParseErrorFn = (s, ex) =>
{
var parts = s.Split('/');
return new DateTime(int.Parse(parts[2]), int.Parse(parts[0]), int.Parse(parts[1]));
};

Assert.That("06/28/2015".FromJsv<DateTime>().ToLongDateString(),
Is.EqualTo("Sunday, June 28, 2015"));
Assert.That("06/28/2015".FromJsv<DateTime>(),
Is.EqualTo(new DateTime(2015, 6, 28)));

DateTimeSerializer.OnParseErrorFn = null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ public void Can_serialize_class_with_list_that_classes_inherited_from_non_abstra
// serialize to JSON using ServiceStack
string jsonString = JsonSerializer.SerializeToString(blockBuster);

const string expected = "{\"Address\":\"Av. República do Líbano, 2175 - Indinópolis, São Paulo - SP, 04502-300\",\"Movies\":[{\"Title\":\"The Shawshank Redemption\",\"ImdbId\":\"tt0111161\",\"Rating\":9.2,\"Director\":\"Frank Darabont\",\"ReleaseDate\":\"\\/Date(792950400000-0000)\\/\",\"TagLine\":\"Fear can hold you prisoner. Hope can set you free.\",\"Genres\":[\"Crime\",\"Drama\"]},{\"__type\":\"ServiceStack.Text.Tests.JsonTests.MovieChild, ServiceStack.Text.Tests\",\"Oscar\":[\"Best Picture - 1972\",\"Best Actor - 1972\",\"Best Adapted Screenplay - 1972\"],\"Title\":\"The Godfather\",\"ImdbId\":\"tt0068646\",\"Rating\":9.2,\"Director\":\"Francis Ford Coppola\",\"ReleaseDate\":\"\\/Date(70214400000-0000)\\/\",\"TagLine\":\"An offer you can't refuse.\",\"Genres\":[\"Crime\",\"Drama\",\"Thriller\"]}]}";
var expected = "{\"Address\":\"Av. República do Líbano, 2175 - Indinópolis, São Paulo - SP, 04502-300\",\"Movies\":[{\"Title\":\"The Shawshank Redemption\",\"ImdbId\":\"tt0111161\",\"Rating\":9.2,\"Director\":\"Frank Darabont\",\"ReleaseDate\":"
+ JsonSerializer.SerializeToString(MoviesData.Movies[0].ReleaseDate) + ",\"TagLine\":\"Fear can hold you prisoner. Hope can set you free.\",\"Genres\":[\"Crime\",\"Drama\"]},{\"__type\":\"ServiceStack.Text.Tests.JsonTests.MovieChild, ServiceStack.Text.Tests\",\"Oscar\":[\"Best Picture - 1972\",\"Best Actor - 1972\",\"Best Adapted Screenplay - 1972\"],\"Title\":\"The Godfather\",\"ImdbId\":\"tt0068646\",\"Rating\":9.2,\"Director\":\"Francis Ford Coppola\",\"ReleaseDate\":"
+ JsonSerializer.SerializeToString(child.ReleaseDate) + ",\"TagLine\":\"An offer you can't refuse.\",\"Genres\":[\"Crime\",\"Drama\",\"Thriller\"]}]}";

Assert.That(jsonString, Is.EqualTo(expected).
Or.EqualTo(expected.Replace("792997200000", "792950400000")
.Replace("70261200000", "70214400000")));
Assert.That(jsonString, Is.EqualTo(expected));
}
}
}
15 changes: 7 additions & 8 deletions tests/ServiceStack.Text.Tests/JsonTests/JsonDateTimeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -523,12 +523,10 @@ public void Can_serialize_json_date_rfc1123_local()
var dateTime = new DateTime(1994, 11, 24, 12, 34, 56, DateTimeKind.Local);
var ssJson = JsonSerializer.SerializeToString(dateTime);

var offsetSpan = TimeZoneInfo.Local.GetUtcOffset(dateTime);
var offset = offsetSpan.ToTimeOffsetString(":");
var dateTimeUtc = dateTime.ToUniversalTime();
var ssJsonUtc = JsonSerializer.SerializeToString(dateTimeUtc);

Assert.That(ssJson, Is.EqualTo(@"""Thu, 24 Nov 1994 04:34:56 GMT"""). //Convert to UTC on wire
Or.EqualTo(@"""Thu, 24 Nov 1994 17:34:56 GMT""").
Or.EqualTo(@"""Thu, 24 Nov 1994 20:34:56 GMT"""));
Assert.That(ssJson, Is.EqualTo(ssJsonUtc)); //Convert to UTC on wire
JsConfig.Reset();
}

Expand All @@ -540,9 +538,10 @@ public void Can_serialize_json_date_rfc1123_unspecified()
var dateTime = new DateTime(1994, 11, 24, 12, 34, 56, DateTimeKind.Unspecified);
var ssJson = JsonSerializer.SerializeToString(dateTime);

Assert.That(ssJson, Is.EqualTo(@"""Thu, 24 Nov 1994 04:34:56 GMT"""). //Convert to UTC on wire
Or.EqualTo(@"""Thu, 24 Nov 1994 17:34:56 GMT""").
Or.EqualTo(@"""Thu, 24 Nov 1994 20:34:56 GMT"""));
var dateTimeUtc = dateTime.ToUniversalTime();
var ssJsonUtc = JsonSerializer.SerializeToString(dateTimeUtc);

Assert.That(ssJson, Is.EqualTo(ssJsonUtc)); //Convert to UTC on wire
JsConfig.Reset();
}

Expand Down
28 changes: 27 additions & 1 deletion tests/ServiceStack.Text.Tests/SerializationHookTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,20 @@ public void JsonSerializer_Deserialize_hooks_on_sub_class()
Assert.That(deserialized.OnDeserializedTouched, Is.True);
}

private void AddSerializeHooksForType<T>()
[Test]
public void JsonSerializer_Deserialize_hooks_set_in_cctor()
{
// Deserialize without serializing first, so we don't call the static constructor of HookTestCctor, which sets its own OnDeserialized callback.

//var original = new HookTestContainer { Child = new HookTestCctor() };
//var json = JsonSerializer.SerializeToString(original);
const string json = "{\"Child\":{\"OnDeserializingTouched\":false,\"OnDeserializedTouched\":false,\"OnSerializingTouched\":true,\"OnSerializedTouched\":false}}";

var deserialized = JsonSerializer.DeserializeFromString<HookTestContainer>(json);
Assert.That(deserialized.Child.OnDeserializedTouched, Is.True);
}

internal static void AddSerializeHooksForType<T>()
{
Type type = typeof(T);
System.Reflection.MethodInfo[] typeMethods = type.GetMethods(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
Expand Down Expand Up @@ -192,5 +205,18 @@ protected void OnSerialized(StreamingContext ctx)
public class HookTestSubClass : HookTestClass
{
}

public class HookTestCctor : HookTestClass
{
static HookTestCctor()
{
AddSerializeHooksForType<HookTestCctor>();
}
}

public class HookTestContainer
{
public HookTestCctor Child { get; set; }
}
}
}