我已经尝试在控制器中使用json,但json总是为null。
你总是得到null的原因是没有声明正确的类型。你不能通过[FromBody]接收一个string类型的动物。
附带说明一下,如果你根本不关心类型,一种方法是声明一个动态类型:
[HttpPost]
public ActionResult Post([FromBody]string json)
public ActionResult Post([FromBody]Dog dog)
{
//现在你可以获得狗了
}
[HttpPost]
public IActionResult Post([FromBody] dynamic json)
{
return new JsonResult(json);
}
在这种情况下,动态类型是
JObject
,您可以将它们转换为任何类型,如您所愿:
public IActionResult Post([FromBody] JObject json)
{
var animal=json.ToObject<Animal>();
var dog = json.ToObject<Dog>();
return new JsonResult(json);
}
如果您现在使用的是控制器,但是这会削减Dog或Cat模型的所有属性。如果您想使用AnimalDto,您应该使属性可访问:
public class AnimalDto
{
public string Name;
public string Name{get;set;}
public string Type;
public string Type{get;set;}
}
[编辑]
What if I want to do this dynamically? Something like:
var animal = json.ToObject<Animal>();
var actualAnimal = json.ToObject<typeof(animal.Type)>();
如果我们想将json转换为特定类型,首先必须知道目标“Type”是什么。但是您的“animal.Type”属性是一个“String”类型,并且可能是按约定命名的字符串。如果此“Type”属性恰好是不带命名空间的类名,例如:
Cat.Type
必须等于Cat
Dog.Type
必须等于Dog
Fish.Type
必须等于Fish
然后您可以使用“Type.GetType()”来解析目标类型。例如:
private Type ResolveAnimalType(string typename,string ns){
if(string.IsNullOrEmpty(ns)){ ns = "App.Models";}
typename= $"{ns}.{typename}";
var type=Type.GetType(
typename,
assemblyResolver:null,
typeResolver: (a,t,ignore)=> a == null ?
Type.GetType(t, false, ignore) :
a.GetType(t, false, ignore),
throwOnError:true,
ignoreCase:false
);
return type;
}
无论如何, 您都可以根据自己的需求自定义解析目标Type
的方式。然后通过方法ToObject<T>()
将JSON对象转换为所需的Type
:
[HttpPost]
public IActionResult Post([FromBody] JObject json)
{
var typename = json.Value<string>("type");
if(String.IsNullOrEmpty(typename))
ModelState.AddModelError("json","any animal must provide a `type` property");
var t= ResolveAnimalType(typename,null);
MethodInfo mi= typeof(JObject)
.GetMethods(BindingFlags.Public|BindingFlags.Instance)
.Where(m=> m.Name=="ToObject" && m.GetParameters().Length==0 && m.IsGenericMethod )
.FirstOrDefault()
?.MakeGenericMethod(t);
var animal = mi?.Invoke(json,null);
return new JsonResult(animal);
}
Animal
的Type
属性必须是Dog
或Cat
之一,并且这与实际使用的子类型相关联(我猜这就是你正在做的),那么你认为通用的JSON解析器会知道这一点吗? - Damien_The_Unbeliever