Skip to content

Commit

Permalink
Merge pull request #116 from feinoujc/custom-content-serializer
Browse files Browse the repository at this point in the history
use converter for merge var content; includes nulls by default
  • Loading branch information
feinoujc authored May 10, 2020
2 parents 8aacf67 + 2f9f9f0 commit 7da13f7
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 12 deletions.
2 changes: 1 addition & 1 deletion src/Mandrill.net/Mandrill.net.csproj
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
</PropertyGroup>

<ItemGroup>
<None Include="logo.png" Pack="true" PackagePath=""/>
<None Include="logo.png" Pack="true" PackagePath="" />
</ItemGroup>


Expand Down
2 changes: 2 additions & 0 deletions src/Mandrill.net/MandrillApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
using System.Net.Http;
using System.Threading.Tasks;
using Mandrill.Model;
using Mandrill.Serialization;
using Newtonsoft.Json;

namespace Mandrill
{
Expand Down
14 changes: 9 additions & 5 deletions src/Mandrill.net/MandrillRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,18 @@ namespace Mandrill
{
internal class MandrillRequest
{
public HttpClient HttpClient { get; }
public string ApiKey { get; }
public HttpClient HttpClient { get; }
public JsonSerializer JsonSerializer { get; }

public MandrillRequest(string apiKey, HttpClient httpClient)
{
if (apiKey == null) throw new ArgumentNullException(nameof(apiKey));
if (httpClient == null) throw new ArgumentNullException(nameof(httpClient));

ApiKey = apiKey;
this.HttpClient = httpClient;
HttpClient = httpClient;
JsonSerializer = MandrillSerializer.Instance;
}

public async Task<TResponse> PostAsync<TRequest, TResponse>(string requestUri, TRequest value) where TRequest : MandrillRequestBase
Expand Down Expand Up @@ -67,12 +71,12 @@ private async Task<T> ReadAsJsonAsync<T>(HttpContent content)
using (var reader = new StreamReader(stream))
using (var jsonReader = new JsonTextReader(reader))
{
return MandrillSerializer<T>.Deserialize(jsonReader);
return JsonSerializer.Deserialize<T>(jsonReader);
}
}

private async Task<HttpResponseMessage> PostAsJsonAsync<T>(string requestUri, T value,
CancellationToken c = default(CancellationToken))
CancellationToken c = default)
{
using (var stream = new MemoryStream())
using (var writer = new StreamWriter(stream))
Expand All @@ -86,7 +90,7 @@ private StreamContent GetStreamContent<T>(T value, StreamWriter writer)
{
using (var jsonWriter = new JsonTextWriter(writer) { CloseOutput = false })
{
MandrillSerializer<T>.Serialize(jsonWriter, value);
JsonSerializer.Serialize(jsonWriter, value);
jsonWriter.Flush();
}
writer.BaseStream.Seek(0, SeekOrigin.Begin);
Expand Down
42 changes: 42 additions & 0 deletions src/Mandrill.net/Serialization/MandrillMergeVarConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System;
using Mandrill.Model;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace Mandrill.Serialization
{
internal class MandrillMergeVarConverter : JsonConverter
{
private readonly JsonSerializer _contentSerializer;

public MandrillMergeVarConverter(JsonSerializerSettings contentSettings)
{
_contentSerializer = JsonSerializer.Create(contentSettings);
}

public override bool CanConvert(Type objectType) => objectType == typeof(MandrillMergeVar);

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}

public override bool CanRead
{
get { return false; }
}

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var mergeVar = (MandrillMergeVar)value;

writer.WriteStartObject();
writer.WritePropertyName("name");
writer.WriteValue(mergeVar.Name);
var content = JToken.FromObject((object)mergeVar.Content, _contentSerializer);
writer.WritePropertyName("content");
content.WriteTo(writer);
writer.WriteEndObject();
}
}
}
16 changes: 10 additions & 6 deletions src/Mandrill.net/Serialization/MandrillSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,23 @@ namespace Mandrill.Serialization
{
public static class MandrillSerializer
{
private static readonly Lazy<JsonSerializer> LazyJsonSerializer = new Lazy<JsonSerializer>(CreateSerializer);
public static JsonSerializer Instance { get; } = Create();

public static JsonSerializer Instance => LazyJsonSerializer.Value;
private static JsonSerializer Create()
{
var settings = CreateSerializerSettings(NullValueHandling.Ignore);
settings.Converters.Add(new MandrillMergeVarConverter(CreateSerializerSettings(NullValueHandling.Include)));
return JsonSerializer.Create(settings);
}

private static JsonSerializer CreateSerializer()
private static JsonSerializerSettings CreateSerializerSettings(NullValueHandling nullValueHandling)
{
var settings = new JsonSerializerSettings { ContractResolver = new MandrillJsonContractResolver() };

settings.Converters.Add(new UnixDateTimeConverter());
settings.Converters.Add(new StringEnumConverter { NamingStrategy = new SnakeCaseNamingStrategy(), AllowIntegerValues = false });
settings.NullValueHandling = NullValueHandling.Ignore;
settings.NullValueHandling = nullValueHandling;
settings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
return JsonSerializer.Create(settings);
return settings;
}
}

Expand Down
1 change: 1 addition & 0 deletions tests/MandrillApiTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using FluentAssertions;
using Mandrill;
using Mandrill.Model;
using Newtonsoft.Json;
using Xunit;

namespace Tests
Expand Down
55 changes: 55 additions & 0 deletions tests/SerializationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,53 @@ public void Can_serialize_content_as_complex_associative_array()
result[1]["unit_price"].Should().Be(0.40);
}

[Fact]
public void Can_serialize_content_including_nulls_by_default()
{
var message = new MandrillMessage();

var data = new { FirstName = "test", LastName = (string)null, Items = new string[0] };

message.GlobalMergeVars.Add(new MandrillMergeVar()
{
Name = "test",
Content = data
});

var json = JObject.FromObject(message, MandrillSerializer.Instance);

json["global_merge_vars"].Should().NotBeEmpty();
var result = json["global_merge_vars"].First["content"];

result.Value<string>("first_name").Should().Be("test");
result["last_name"].Should().NotBeNull();
result["last_name"].Value<string>().Should().BeNull();
result["items"].Should().NotBeNull();
result["items"].ToArray().Should().BeEmpty();
}

[Fact]
public void Can_serialize_merge_var_content_using_custom_settings()
{
var message = new MandrillMessage();
var data = new ContentModel { FirstName = "test", LastName = null };

message.GlobalMergeVars.Add(new MandrillMergeVar()
{
Name = "test",
Content = data
});

var json = JObject.FromObject(message, MandrillSerializer.Instance);

json["global_merge_vars"].Should().NotBeEmpty();
var result = json["global_merge_vars"].First["content"];

result.Value<string>("FirstName").Should().Be("test");
result["LastName"].Should().NotBeNull();
result["LastName"].Value<string>().Should().BeNull();
}

[Fact]
public void Can_set_property_name_by_convention()
{
Expand Down Expand Up @@ -497,5 +544,13 @@ static Int64 ToUnixTime(DateTime self)
var delta = self - epoc;
return (long)delta.TotalSeconds;
}

private class ContentModel
{
[JsonProperty("FirstName")]
public string FirstName { get; set; }
[JsonProperty("LastName")]
public string LastName { get; set; }
}
}
}

0 comments on commit 7da13f7

Please sign in to comment.