我已经尝试在控制器中使用 json 。但是 json 总是 null
你总是得到的原因null
是你没有声明正确Type
。你不应该收到string
动物类型通过[FromBody]
.
[HttpPost]
public ActionResult Post([FromBody]string json)
public ActionResult Post([FromBody]Dog dog)
{
// now you get the dog
}
附带说明一下,如果您根本不关心类型,一种方法是声明一个dynamic
type:
[HttpPost]
public IActionResult Post([FromBody] dynamic json)
{
return new JsonResult(json);
}
在这种情况下,动态类型是JObject
,您可以根据需要将它们转换为任何类型:
public IActionResult Post(/*[ModelBinder(typeof(AnimalModelBinder))]*/[FromBody] JObject json)
{
var animal=json.ToObject<Animal>();
var dog = json.ToObject<Dog>();
return new JsonResult(json);
}
现在是我的控制器,但这会切断狗或猫模型的所有属性
如果您想使用AnimalDto
,您应该使属性可访问:
public class AnimalDto
{
public string Name;
public string Name{get;set;}
public string Type;
public string Type{get;set;}
}
[Edit]
如果我想动态地执行此操作怎么办?就像是:
var animal = json.ToObject<Animal>();
var actualAnimal = json.ToObject<typeof(animal.Type)>();
如果我们想将 json 转换为某种特定类型,我们首先必须知道目标是什么Type
是 。但你的animal.Type
财产是一种类型String
,这可能是一个约定的字符串。如果这Type
property 正是没有命名空间的类名,例如
-
Cat.Type
必须等于Cat
-
Dog.Type
必须等于Dog
-
Fish.Type
必须等于Fish
那么你可以使用Type.GetType()
解析目标类型。例如 :
// typename : the Animal.Type property
// ns : the namespace string
private Type ResolveAnimalType(string typename,string ns){
if(string.IsNullOrEmpty(ns)){ ns = "App.Models";}
typename= $"{ns}.{typename}";
var type=Type.GetType(
typename,
assemblyResolver:null, // if you would like load from other assembly, custom this resovler
typeResolver: (a,t,ignore)=> a == null ?
Type.GetType(t, false, ignore) :
a.GetType(t, false, ignore),
throwOnError:true,
ignoreCase:false
);
return type;
}
Anyway, 您可以自定义我们解决目标的方式Type
根据您自己的需求。进而将 json 对象转换为你想要的Type
按方法ToObject<T>()
:
[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");
// resolve the target type
var t= ResolveAnimalType(typename,null);
// get the method of `.ToObject<T>()`
MethodInfo mi= typeof(JObject)
.GetMethods(BindingFlags.Public|BindingFlags.Instance)
.Where(m=> m.Name=="ToObject" && m.GetParameters().Length==0 && m.IsGenericMethod )
.FirstOrDefault()
?.MakeGenericMethod(t); // ToObject<UnknownAnimialType>()
var animal = mi?.Invoke(json,null);
return new JsonResult(animal);
}