Search code examples
c#urisystem.text.json

Why Do I Only Receive The Uri String When Serializing A Uri Using JsonSerializer?


I'm sure this is a 'wrong question' but here goes!

I'd like to serialize Uri properties in Json format.

However, when I attempt to do something like:

var jsonResults = System.Text.Json.JsonSerializer.Serialize(uri);

All I get in return is the actual Uri string, not its properties and values.

According to documentation like this: https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/how-to?pivots=dotnet-8-0

It should serialize properties of the object into the string with their names and values, unless I've completely misunderstood something.

I've kind of made a unsophisticated method of doing this using string builder to show you the values I'm talking about. They would be these:

[Uri Result Data]

Absolute Uri: [https://westmd.craigslist.org/]

Absolute Path: [/]

Scheme: [https]

Host: [westmd.craigslist.org]

Port: [443]

Path & Query: [/]

DnsSafeHost: [westmd.craigslist.org]

Authority: [westmd.craigslist.org]

Fragment: []

Scheme & Server: [https://westmd.craigslist.org]

IdnHost: [westmd.craigslist.org]

Default Port: [True]

Host Name Type: [Dns]

User Info: []

[Uri Segments]:

However, when using the line of code above, for JsonSerialization, all it returns is..

[JSON]: "https://westmd.craigslist.org/"

Based on the documentation I've read, and stack articles I've read, the JsonSerialization should have these properties and their values, even if un-indented by default.

I've simply used the function laid out in the MSDN documentation and expected results similar to the ones shown,

string jsonString = JsonSerializer.Serialize(weatherForecast);

With results of..

{"Date":"2019-08-01T00:00:00-07:00","TemperatureCelsius":25,"Summary":"Hot"}

as per The MSDN Documentation

I'm not sure if there's a specific methodology or a different way you have to go about this with a Uri than other objects, but any help would be much appreciated.


Solution

  • There might be a hidden Uri converter somewhere in c# code that uses ToString() representation, like System.UriTypeConverter, explaining the output format.

    These properties you want are in fact useless, cause most of them like AbsoluteUri have no setter, meaning you won't be able to deserialize them ;)

    If you absolutely want a custom serialization/deserialization of this framework object, you will have to code your own converter, but I'm not sure this is a good idea.

    If this is the case, look at JsonConverter<T> base class you will have to inherit from.

    Here a startup for serializing at your convenience

    public class UriConverter : JsonConverter<Uri>
    {
        public override Uri? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            throw new NotImplementedException();
        }
    
        public override void Write(Utf8JsonWriter writer, Uri value, JsonSerializerOptions options)
        {
            writer.WriteStartObject();
            writer.WriteString("absoluteUri", value.AbsoluteUri);
            writer.WriteNumber("port", value.Port);
            writer.WriteEndObject();
        }
    }
    

    Then use it like this

    var options = new JsonSerializerOptions();
    var converter = new UriConverter();
    
    options.Converters.Add(converter);
    
    var uri = new Uri("https://localhost:9044/admin");
    var json = System.Text.Json.JsonSerializer.Serialize(uri, options);