You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用JsonSerializer序列化Uri为何仅返回Uri字符串而非属性?

解决System.Text.Json序列化Uri仅输出字符串的问题

System.Text.Json对Uri类型有内置序列化逻辑,默认只会输出它的字符串表示(即调用ToString()的结果),所以直接序列化Uri对象时只会得到Uri字符串,而非其属性集合。要实现序列化Uri的属性,有两种常用方案:

方案一:自定义JsonConverter

创建自定义转换器来控制Uri的序列化行为,按需输出需要的属性:

public class UriConverter : JsonConverter<Uri>
{
    public override void Write(Utf8JsonWriter writer, Uri value, JsonSerializerOptions options)
    {
        writer.WriteStartObject();
        // 按需添加你需要的Uri属性
        writer.WriteString("AbsoluteUri", value.AbsoluteUri);
        writer.WriteString("Scheme", value.Scheme);
        writer.WriteString("Host", value.Host);
        writer.WriteNumber("Port", value.Port);
        writer.WriteString("PathAndQuery", value.PathAndQuery);
        writer.WriteString("LocalPath", value.LocalPath);
        writer.WriteEndObject();
    }

    public override Uri Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        // 实现反序列化逻辑(如果需要),这里从AbsoluteUri重构Uri
        using var doc = JsonDocument.ParseValue(ref reader);
        var absoluteUri = doc.RootElement.GetProperty("AbsoluteUri").GetString();
        return new Uri(absoluteUri);
    }
}

使用时将转换器加入序列化配置:

var uri = new Uri("https://example.com/api/forecast?city=shanghai");
var options = new JsonSerializerOptions { Converters = { new UriConverter() } };
var json = JsonSerializer.Serialize(uri, options);

输出的JSON会是包含指定属性的对象:

{
  "AbsoluteUri": "https://example.com/api/forecast?city=shanghai",
  "Scheme": "https",
  "Host": "example.com",
  "Port": 443,
  "PathAndQuery": "/api/forecast?city=shanghai",
  "LocalPath": "/api/forecast"
}

如果是在类的属性中使用Uri,还可以通过特性指定转换器:

public class WeatherForecast
{
    public DateTime Date { get; set; }
    public int TemperatureCelsius { get; set; }
    [JsonConverter(typeof(UriConverter))]
    public Uri ForecastSource { get; set; }
}

方案二:创建Uri数据传输对象(DTO)

如果不需要全局修改Uri的序列化行为,只是特定场景需要输出属性,可以创建一个DTO类映射Uri的属性,序列化这个DTO:

public class UriInfo
{
    public string AbsoluteUri { get; set; }
    public string Scheme { get; set; }
    public string Host { get; set; }
    public int Port { get; set; }
    public string PathAndQuery { get; set; }

    public static UriInfo FromUri(Uri uri)
    {
        return new UriInfo
        {
            AbsoluteUri = uri.AbsoluteUri,
            Scheme = uri.Scheme,
            Host = uri.Host,
            Port = uri.Port,
            PathAndQuery = uri.PathAndQuery
        };
    }
}

使用示例:

var uri = new Uri("https://example.com/api/forecast?city=shanghai");
var uriInfo = UriInfo.FromUri(uri);
var json = JsonSerializer.Serialize(uriInfo);

这种方式更灵活,适合临时需要序列化Uri属性的场景。

内容的提问来源于stack exchange,提问作者user22301082

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 23:22:37