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

使用Refit发送含Uri属性的类作为POST接口参数时Uri值异常问题

问题根因

该问题和Refit框架本身无关,是Newtonsoft.Json默认的Uri类型序列化逻辑导致的:默认序列化Uri时会调用ToString()方法,对于file://协议的Uri,ToString()会省略协议前缀,仅返回路径部分。

定位方法

在客户端本地直接序列化测试即可复现问题:

var test = new SomeClass { Uri = new Uri("file:///var/share") };
var serializeResult = JsonConvert.SerializeObject(test);
// 输出结果为 {"Uri":"/var/share"},和服务端收到的内容一致,可确认是序列化环节的问题
解决方案

提供两种可行的修复方式,可根据业务场景选择:

  • 方案1:自定义Uri序列化转换器(无侵入修改,不用调整原有实体结构)
    首先实现自定义JsonConverter:
public class UriAbsoluteConverter : JsonConverter<Uri>
{
    public override void WriteJson(JsonWriter writer, Uri value, JsonSerializer serializer)
    {
        // 序列化时取完整的AbsoluteUri
        writer.WriteValue(value?.AbsoluteUri);
    }

    public override Uri ReadJson(JsonReader reader, Type objectType, Uri existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        var uriStr = reader.Value?.ToString();
        return string.IsNullOrWhiteSpace(uriStr) ? null : new Uri(uriStr);
    }
}

将转换器注册到Refit的序列化配置中:

var jsonSettings = new JsonSerializerSettings
{
    Converters = new List<JsonConverter> { new UriAbsoluteConverter() }
};
var refitSettings = new RefitSettings(new NewtonsoftJsonContentSerializer(jsonSettings));
_apiRefit = RestService.For<ISomeApi>("http://localhost:5000", refitSettings);
  • 方案2:调整实体属性类型(改动最小,无需额外配置)
    将实体类的Uri属性改为string类型,赋值时直接传入Uri的AbsoluteUri值,服务端也对应调整为string接收,需要使用Uri类型时再手动转换即可:
[Serializable]
public class SomeClass
{
    // 赋值示例:someClass.Uri = yourUri.AbsoluteUri;
    public string Uri { get; set; }
}

两种方案均能保证传输的Uri携带完整的协议前缀,服务端可正常解析。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 20:36:03