[英]ASP.NET Core Web API Automatic JSON Parameter Deserialization Not Working
I've a simple controller that takes one parameter from the POST request body. 我有一个简单的控制器,它从POST请求主体中获取一个参数。 Normally it should automatically deserialize it from JSON to the object type but it fails. 通常,它应该自动将其从JSON反序列化为对象类型,但失败。 When I try to deserialize it myself it works withot problems. 当我自己尝试反序列化时,它会遇到很多问题。 Here is some code: 这是一些代码:
The controller (the documentCommand variable is null): 控制器(documentCommand变量为null):
public async Task<IActionResult> Create([FromBody]CreateDocumentCommand documentCommand)
{
if (documentCommand == null)
{
return StatusCode(403); //Deserialization fails, documentCommand is null
}
//we have to reach this :(
return Json(documentCommand.Document.Id);
}
Here is how I serialize it and how I test if it will be able to deserialize it: 这是我如何序列化它以及如何测试它是否可以反序列化它:
JsonSerializerSettings jsonSerializerSettings = new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Auto,
NullValueHandling = NullValueHandling.Ignore,
MissingMemberHandling = MissingMemberHandling.Ignore
};
string serialized = JsonConvert.SerializeObject(item, jsonSerializerSettings);
CreateDocumentCommand deserialized = JsonConvert.DeserializeObject<CreateDocumentCommand>(serialized, jsonSerializerSettings);
In my CreateDocumentCommand class I have an interface property and when I remove the TypeNameHandling = TypeNameHandling.Auto it fails in the second example too. 在我的CreateDocumentCommand类中,我有一个接口属性,当我删除TypeNameHandling = TypeNameHandling.Auto时,它在第二个示例中也会失败。
Is there a way yo tell the MVC deserializer to take the TypeNameHandling into account? 有没有办法告诉MVC解串器考虑TypeNameHandling ? It seems to me that it skips it. 在我看来,它跳过了它。
EDIT Some more code: 编辑更多代码:
public class CreateDocumentCommand : Command, ICreateDocumentCommand
{
public CreateDocumentCommand()
{
}
public IDocument Document { get; set; }
}
MY SOLUTION: Added that ConcreteTypeConverter which I found at the link provided by Babak Naffas and made some changes because I was getting some circular reference exeptions. 我的解决方案:添加了我在Babak Naffas提供的链接中找到的ConcreteTypeConverter,并进行了一些更改,因为我得到了一些循环参考实例。 Also Added the [JsonConverter(typeof(ConcreteTypeConverter))] beefore the CreateDocumentCommand class. 还添加了[JsonConverter(typeof(ConcreteTypeConverter))]增强CreateDocumentCommand类。
public class ConcreteTypeConverter<T> : JsonConverter
{
static bool read = false;
public override bool CanConvert(Type objectType)
{
return typeof(T).IsAssignableFrom(objectType);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
serializer.TypeNameHandling = TypeNameHandling.Auto;
serializer.NullValueHandling = NullValueHandling.Ignore;
serializer.MissingMemberHandling = MissingMemberHandling.Ignore;
return serializer.Deserialize<T>(reader);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.Serialize(writer, value);
}
public override bool CanWrite
{
get
{
return false;
}
}
public override bool CanRead
{
get
{
read = !read;
return read;
}
}
}
Your issue is the IDocument interface, which can't be deserialized out of the box as the deserializer can't know which concrete class to use. 您的问题是IDocument接口,由于解串器无法知道要使用哪个具体类,因此无法直接对它进行反序列化。
Also, make sure to create a unit test that takes the raw JSON that you'd be passing to your controller method and make sure it can be deserialized. 另外,请确保创建一个单元测试,该单元测试将要传递给控制器方法的原始JSON并确保可以反序列化。
If you want global setting then you can specify JsonSerializerSetting
at application level using AddJsonOptions
extension. 如果需要全局设置,则可以使用AddJsonOptions
扩展名在应用程序级别指定JsonSerializerSetting
。 Read it about here . 在这里阅读。
services.AddMvc()
.AddJsonOptions(opt =>
{
if (opt.SerializerSettings != null)
{
opt.SerializerSettings.TypeNameHandling = TypeNameHandling.Auto,
opt.SerializerSettings.NullValueHandling = NullValueHandling.Ignore,
opt.SerializerSettings.MissingMemberHandling = MissingMemberHandling.Ignore
}
});
AddJsonOptions is defined in Microsoft.AspNetCore.Mvc.Formatters.Json nuget package. AddJsonOptions在Microsoft.AspNetCore.Mvc.Formatters.Json nuget包中定义。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.