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

.NET 8中如何声明TypeConverter控制类序列化以兼容现有API响应

问题

我有一个已上线的ASP.NET Core 8 Web API项目,希望修改返回类型,但不能更改现有响应JSON格式(因为服务已投入生产)。

原有Web方法示例:

public async Task<JsonResult> InsertItem(InsertItemInput oInputParams)
{
    Stopwatch oStopWatch = Stopwatch.StartNew();
    int iResult = 0;
    iResult = // 数据库插入逻辑

    return new JsonResult(new 
                          {
                              StatusCode = (int)HttpStatusCode.OK,
                              Exception = (object)null,
                              Result = iResult,
                              ServiceFullElapsed = oStopWatch.Elapsed.TotalMilliseconds
                          });
}

返回的JSON格式:

{
    "StatusCode": 200,
    "Exception": null,
    "Result": 157,
    "ServiceFullElapsed": 140.2169
}

我为结果创建了模型类:

[TypeConverter(typeof(ReadWriteResultJsonConvert))]
public class ReadWriteResult
{
    public int Code {  get; set; }
}

对应的转换器类:

public class ReadWriteResultJsonConvert : Newtonsoft.Json.JsonConverter<ReadWriteResult>
{
    public override void WriteJson(JsonWriter writer, ReadWriteResult value, Newtonsoft.Json.JsonSerializer serializer)
    {
        var obj = (JObject)JToken.FromObject(value.Code);
        obj.WriteTo(writer);
    }

    public override ReadWriteResult ReadJson(JsonReader reader, Type objectType, ReadWriteResult existingValue, bool hasExistingValue, Newtonsoft.Json.JsonSerializer serializer)
    {
        return existingValue;
    }
}

修改后的Web方法:

public async Task<JsonResult> InsertItem(InsertItemInput oInputParams)
{
    Stopwatch oStopWatch = Stopwatch.StartNew();
    ReadWriteResult oResult = new ReadWriteResult();
    oResult.Code = // 数据库插入逻辑

    return new JsonResult(new
                          {
                              StatusCode = (int)HttpStatusCode.OK,
                              Exception = (object)null,
                              Result = oResult,
                              ServiceFullElapsed = oStopWatch.Elapsed.TotalMilliseconds
                          });
}

但转换器从未被调用,返回结果变成了:

{
    "StatusCode": 200,
    "Exception": null,
    "Result": { "Code": 157 },
    "ServiceFullElapsed": 28064.9097
}

我希望返回"Result":157而非"Result": { "Code": 157 },请问如何让ReadWriteResult类序列化时仅输出Code属性的值?


解决方案

方法1:修正Newtonsoft.Json转换器配置

你误用了[TypeConverter]特性,它是用于.NET原生类型转换的,并非Newtonsoft.Json的序列化标记。需要改用[JsonConverter]特性标记模型类,同时简化转换器逻辑:

// 替换TypeConverter为JsonConverter特性
[JsonConverter(typeof(ReadWriteResultJsonConvert))]
public class ReadWriteResult
{
    public int Code { get; set; }
}

修正转换器的WriteJson方法,直接写入整数即可:

public class ReadWriteResultJsonConvert : Newtonsoft.Json.JsonConverter<ReadWriteResult>
{
    public override void WriteJson(JsonWriter writer, ReadWriteResult value, Newtonsoft.Json.JsonSerializer serializer)
    {
        // 直接输出Code的整数值
        writer.WriteValue(value.Code);
    }

    public override ReadWriteResult ReadJson(JsonReader reader, Type objectType, ReadWriteResult existingValue, bool hasExistingValue, Newtonsoft.Json.JsonSerializer serializer)
    {
        // 反序列化时从整数还原对象
        if (reader.TokenType == JsonToken.Integer)
        {
            return new ReadWriteResult { Code = (int)reader.Value };
        }
        return existingValue ?? new ReadWriteResult();
    }
}

方法2:添加隐式类型转换

如果不想用转换器,可以给ReadWriteResult类添加隐式转换为int的逻辑,这样赋值时可直接把对象当作整数使用:

public class ReadWriteResult
{
    public int Code { get; set; }

    // 隐式转换为int
    public static implicit operator int(ReadWriteResult result)
    {
        return result.Code;
    }

    // 可选:支持从int转换为ReadWriteResult
    public static implicit operator ReadWriteResult(int code)
    {
        return new ReadWriteResult { Code = code };
    }
}

修改Web方法中的Result赋值(可显式转换或依赖隐式自动转换):

return new JsonResult(new
                      {
                          StatusCode = (int)HttpStatusCode.OK,
                          Exception = (object)null,
                          Result = (int)oResult,
                          ServiceFullElapsed = oStopWatch.Elapsed.TotalMilliseconds
                      });

方法3:适配System.Text.Json(ASP.NET Core 8默认序列化器)

如果项目使用的是System.Text.Json而非Newtonsoft.Json,需要编写对应的转换器:

[System.Text.Json.Serialization.JsonConverter(typeof(ReadWriteResultSystemTextJsonConverter))]
public class ReadWriteResult
{
    public int Code { get; set; }
}

public class ReadWriteResultSystemTextJsonConverter : System.Text.Json.Serialization.JsonConverter<ReadWriteResult>
{
    public override ReadWriteResult Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        if (reader.TokenType == JsonTokenType.Number)
        {
            return new ReadWriteResult { Code = reader.GetInt32() };
        }
        return default;
    }

    public override void Write(Utf8JsonWriter writer, ReadWriteResult value, JsonSerializerOptions options)
    {
        writer.WriteNumberValue(value.Code);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 15:23:12