摘要:最近在迁移一个老项目的接口到另一个新项目中,为了前端同事最小修改,所以响应的格式等最好保持不变,然后在使用中发现了老项目中如果遇到返回值的内容包含枚举,就将其转为枚举字符串内容进行返回,然后就出现了下面的修改。
最近在迁移一个老项目的接口到另一个新项目中,为了前端同事最小修改,所以响应的格式等最好保持不变,然后在使用中发现了老项目中如果遇到返回值的内容包含枚举,就将其转为枚举字符串内容进行返回,然后就出现了下面的修改。
新建一个.Net8 Api项目,然后增加一个枚举
public enumSexInfo{
None,
Man,
Woman
}
修改默认的控制器WeatherForecastController的Get方法返回值增加
public class WeatherForecast{
public DateOnly Date{get;set;}
publicint TemperatureC{get;set;}
publicint TemperatureF=>32+(int)(TemperatureC/0.5556);
publicstring? Summary{get;set;}
public SexInfo Sex{get;set;}// 👈
}
然后在Api的方法中默认写死一个性别返回值
[HttpGet(Name = "GetWeatherForecast")]public IEnumerable Get
{
return Enumerable.Range(1,5).Select(index =>newWeatherForecast
{
Date=DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
Sex=SexInfo.Man,// 👈
TemperatureC=Random.Shared.Next(-20,55),
Summary=Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray;
}
本来以为就是这一个接口需要这么处理,那么我就随便堆一下吧,只需要修改返回类
using Newtonsoft.Json;public class WeatherForecast
{
public DateOnly Date{get;set;}
publicint TemperatureC{get;set;}
publicint TemperatureF=>32+(int)(TemperatureC/0.5556);
publicstring? Summary{get;set;}
[JsonIgnore]
public SexInfo Sex{get;set;}
[JsonProperty("sex")]
publicstring SexStr=>Sex.ToString;// 👈
}
其他不需要改动,然后查看返回值
[{
"date":"2024-12-22",
"temperatureC":-8,
"temperatureF":18,
"summary":"Warm",
"sex":"Man"
},
{
"date":"2024-12-23",
"temperatureC":49,
"temperatureF":120,
"summary":"Scorching",
"sex":"Man"
}
...
]
这个效果就是满足需求的,那么就暂且这么搞吧。
同事在写其他接口的时候也遇到了这个情况,然后他并没有这么做,这个项目是已经引用了Microsoft.AspNetCore.Mvc.NewtonsoftJson包(替代默认的序列化包使用NewtonsoftJson进行处理),且已经配置了下面代码
builder.Services.AddControllers.AddNewtonsoftJson; // 👈
我将他修改的伪代码返回值类放出来
using Newtonsoft.Json.Converters;using System.Text.Json.Serialization;
namespace WebApplication1;
public class WeatherForecast
{
public DateOnly Date{get;set;}
publicint TemperatureC{get;set;}
publicint TemperatureF=>32+(int)(TemperatureC/0.5556);
publicString? Summary{get;set;}
[JsonConverter(typeof(StringEnumConverter))]// 👈
public SexInfo Sex{get;set;}
}
publicenum SexInfo
{
None,
Man,
Woman
}
同样只是返回类做了处理,API方法里面并没有做特殊处理,但是前端反馈有问题,没有返回的枚举字符串???
[{
"date":"2024-12-22",
"temperatureC":-16,
"temperatureF":4,
"summary":"Sweltering",
"sex":1
},
{
"date":"2024-12-23",
"temperatureC":6,
"temperatureF":42,
"sex":1
},
这个就很奇怪了,因为我对这个返回值中枚举做序列化操作StringEnumConverter不熟练,那么只好去搜一下了,看到有人说,你应该在AddNewtonsoftJson中进行配置一下
builder.Services.AddControllers.AddNewtonsoftJson(options =>
{
options.SerializerSettings.Converters.Add(new StringEnumConverter);
});
我将配置修改成这个样子后,发现返回了枚举的字符串后,虽然略有疑惑,但是还是果断提交了代码,此刻我理解的逻辑是,需要下面两个东西都配置才能实现枚举转枚举字符串
1、属性标注StringEnumConverter2、options.SerializerSettings.Converters.Add(new StringEnumConverter);引起了其他问题
前端反馈该项目的其他部分接口本来枚举应该返回枚举值的,现在也返回枚举字符串了,我???其他模型我记得是没有做特殊操作的,难得共用了模型类吗?结果是没有的,那么就应该再检查下哪里有点不对劲呀?在Program.cs中AddNewtonsoftJson应该是全局配置的意思,应该是这个导致的,那么为啥我针对单个模型设置不生效那?返回过去一检查,竟然是这么回事
using Newtonsoft.Json;// 正确的using Newtonsoft.Json.Converters;
//using System.Text.Json.Serialization; // 错误的
namespaceWebApplication1;
publicclassWeatherForecast
{
public DateOnly Date{get;set;}
publicint TemperatureC{get;set;}
publicint TemperatureF=>32+(int)(TemperatureC/0.5556);
publicstring? Summary{get;set;}
[JsonConverter(typeof(StringEnumConverter))]
public SexInfo Sex{get;set;}
}
publicenum SexInfo
{
None,
Man,
Woman
}
这个时候还原下面代码
builder.Services.AddControllers.AddNewtonsoftJson(options =>
{
//options.SerializerSettings.Converters.Add(new StringEnumConverter);
});
这样子就可以实现,如果接口中的返回值的枚举想返回枚举字符串就特殊处理,不需要的就不处理,默认返回枚举值了(当然还是更建议统一下返回值)
来源:opendotnet