使用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
相关产品推荐
相关产品推荐

