如何在Model类中接收API字符串并转换为JSON对象?
问题描述
希望API接收请求时,将传入的字符串转换为AS_AscContext类型的JSON对象。使用Postman发送请求,但通过模型类的自定义转换器无法完成转换,相关代码如下:
模型类与自定义JSON转换器
namespace WebApplication2.Models { [Serializable] public class Test { [JsonConverter(typeof(UserConverter))] public AS_AscContext AscParcelContext { get; set; } } public class AS_AscContext { public string ShellType { get; set; } public string LayoutName { get; set; } } public class UserConverter : JsonConverter { private readonly Type[] _types; public UserConverter(params Type[] types) { _types = types; } public override void WriteJson(JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer) { JToken t = JToken.FromObject(value); if (t.Type != JTokenType.Object) { t.WriteTo(writer); } else { JObject o = (JObject)t; IList<string> propertyNames = o.Properties().Select(p => p.Name).ToList(); o.AddFirst(new JProperty("Keys", new JArray(propertyNames))); o.WriteTo(writer); } } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer) { throw new NotImplementedException("Unnecessary because CanRead is false. The type will skip the converter."); } public override bool CanRead { get { return false; } } public override bool CanConvert(Type objectType) { return _types.Any(t => t == objectType); } } }
接收请求的控制器代码
[HttpPost] public IActionResult Privacy([FromBody]Test aS_AggregatorRequest) { return View(); }
Postman中发送的请求内容对应截图展示的格式。
问题分析
- 转换器无反序列化能力:当前
UserConverter仅实现了序列化(WriteJson)逻辑,ReadJson直接抛异常且CanRead设为false,导致API接收请求时,不会用该转换器将字符串解析为目标对象。 - 转换器匹配逻辑失效:在
[JsonConverter(typeof(UserConverter))]属性中未传入Type参数,CanConvert方法返回false,转换器根本不会被触发。 - 请求格式可能不匹配:如果Postman发送的是带引号的JSON字符串(而非直接的JSON对象),未做正确转义的话,默认解析逻辑无法识别。
解决方案
方案1:修复自定义转换器,实现反序列化逻辑
修改UserConverter,使其支持将字符串解析为AS_AscContext对象,同时调整类型匹配逻辑:
public class UserConverter : JsonConverter { // 直接针对AS_AscContext类型处理,无需动态传入Type public override bool CanConvert(Type objectType) { return objectType == typeof(AS_AscContext); } public override void WriteJson(JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer) { // 保留原序列化逻辑(如果需要) JToken t = JToken.FromObject(value); if (t.Type != JTokenType.Object) { t.WriteTo(writer); } else { JObject o = (JObject)t; IList<string> propertyNames = o.Properties().Select(p => p.Name).ToList(); o.AddFirst(new JProperty("Keys", new JArray(propertyNames))); o.WriteTo(writer); } } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer) { // 兼容两种输入:直接的JSON对象,或字符串形式的JSON if (reader.TokenType == JsonToken.String) { // 字符串转JSON对象再解析 string jsonStr = reader.Value.ToString(); return JsonConvert.DeserializeObject<AS_AscContext>(jsonStr); } else if (reader.TokenType == JsonToken.StartObject) { // 直接解析JSON对象 return serializer.Deserialize<AS_AscContext>(reader); } throw new JsonSerializationException("无法解析为AS_AscContext类型"); } public override bool CanRead { get { return true; } } }
方案2:移除自定义转换器,使用默认解析
如果Postman原本发送的就是标准JSON对象,无需自定义转换器,Newtonsoft.Json默认就能完成解析:
修改模型类:
[Serializable] public class Test { // 移除自定义转换器,使用默认解析逻辑 public AS_AscContext AscParcelContext { get; set; } }
Postman请求Body示例(标准JSON格式):
{ "AscParcelContext": { "ShellType": "test", "LayoutName": "layout1" } }
方案3:规范Postman请求格式
如果必须传入字符串形式的JSON(如"{\"ShellType\":\"test\",\"LayoutName\":\"layout1\"}"),需在Postman中正确转义字符串,并搭配方案1的转换器使用。
内容的提问来源于stack exchange,提问作者Parjanya Kumar
相关产品推荐
相关产品推荐

