System.Text.Json IP address & port serialization

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.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.