Part of the series: Fun with System.Text.Json
The other day I was porting some code to .NET Core that is responsible for consuming the IP addresses sent to our service as part of the X-Forwarded-For
Http header. That in and of itself was a pretty interesting adventure, one which I should probably write-up for some good entertainment, but the point of this post is what I noticed when I logged the final parsed IPAddress
(the one I select as the client’s true IP). The result wasn’t exactly what I was expecting:
at System.Net.IPAddress.get_ScopeId() at System.Text.Json.JsonPropertyInfoNotNullable`4.OnWrite(WriteStackFrame& current, Utf8JsonWriter writer) at System.Text.Json.JsonPropertyInfo.Write(WriteStack& state, Utf8JsonWriter writer) at System.Text.Json.JsonSerializer.Write(Utf8JsonWriter writer, Int32 originalWriterDepth, Int32 flushThreshold, JsonSerializerOptions options, WriteStack& state) at System.Text.Json.JsonSerializer.WriteCore(Utf8JsonWriter writer, Object value, Type type, JsonSerializerOptions options) at System.Text.Json.JsonSerializer.WriteCore(PooledByteBufferWriter output, Object value, Type type, JsonSerializerOptions options) at System.Text.Json.JsonSerializer.WriteCoreString(Object value, Type type, JsonSerializerOptions options) at System.Text.Json.JsonSerializer.Serialize[TValue](TValue value, JsonSerializerOptions options)
An unhandled exception?! Looks like System.Text.Json doesn’t support the System.Net IPAddress
type! By extension, it also does not support its cousin IPEndPoint
.
This will not stand, ya know, this aggression will not stand, man.
The Big Lebowski
Since I already have this package full of System.Text.Json converters, I figured I would add a couple new ones to get us out of this bind: JsonIPAddressConverter & JsonIPEndPointConverter. Now available as part of Macross.Json.Extensions.
Used as one might expect:
public class TestClass { [JsonConverter(typeof(JsonIPAddressConverter))] public IPAddress IPAddress { get; set; } [JsonConverter(typeof(JsonIPEndPointConverter))] public IPEndPoint IPEndPoint { get; set; } }
The output is what you get calling ToString
on the objects:
{ "IPv4Address": "127.0.0.1", "IPv6Address": "::1", "IPv4EndPoint": "127.0.0.1:443", "IPv6EndPoint": "[::1]:443" }
The rug really did tie the room together.