Web API 无法使用 GET 绑定不可变对象,但可以使用 POST
Web API cannot bind Immutable object with GET but can with POST
我想用 GET 方法绑定不可变模型。它适用于 POST。为什么?
[HttpGet]
public string Get([FromQuery]Something something)
{
return "value";
}
[HttpPost]
public void Post([FromBody]Something something)
{
}
public class Something
{
public string Prop1 { get; }
public int Prop2 { get; }
public Something(string prop1, int prop2)
{
Prop1 = prop1;
Prop2 = prop2;
}
}
使用 GET 方法我得到异常:
InvalidOperationException: Could not create an instance of type
WebApplication2.Something;. Model bound complex types must not be
abstract or value types and must have a parameterless constructor.
是否与[FromQuery]
和[FromBody]
属性有关?
[HttpGet]
public string Get([FromQuery]Something something)
{
return "value";
}
[FromQuery]Something something
参数要求您发送该类型的对象。您不能在查询字符串中执行此操作,因为它只能接受 "simple types",例如 int
和 string
[FromBody]
属性标志到 MVC 管道,以使用配置的格式化程序绑定来自请求正文的数据。根据请求的内容类型选择格式化程序。
JsonInputFormatter
是默认格式化程序,基于 Json.NET,它只是执行 JSON 字符串主体反序列化 (code):
model = jsonSerializer.Deserialize(jsonReader, type);
因为在反序列化过程中对象的构造函数没有被调用,你没有任何错误,比如“必须有一个无参数的构造函数”。
相反,对于 [FromQuery]Something
ComplexTypeModelBinder is used and it first creates an instance of your Something
class by calling default constructor and then assign corresponding values to public properties. Check BindModelCoreAsync method for implementation details。
我想用 GET 方法绑定不可变模型。它适用于 POST。为什么?
[HttpGet]
public string Get([FromQuery]Something something)
{
return "value";
}
[HttpPost]
public void Post([FromBody]Something something)
{
}
public class Something
{
public string Prop1 { get; }
public int Prop2 { get; }
public Something(string prop1, int prop2)
{
Prop1 = prop1;
Prop2 = prop2;
}
}
使用 GET 方法我得到异常:
InvalidOperationException: Could not create an instance of type WebApplication2.Something;. Model bound complex types must not be abstract or value types and must have a parameterless constructor.
是否与[FromQuery]
和[FromBody]
属性有关?
[HttpGet]
public string Get([FromQuery]Something something)
{
return "value";
}
[FromQuery]Something something
参数要求您发送该类型的对象。您不能在查询字符串中执行此操作,因为它只能接受 "simple types",例如 int
和 string
[FromBody]
属性标志到 MVC 管道,以使用配置的格式化程序绑定来自请求正文的数据。根据请求的内容类型选择格式化程序。
JsonInputFormatter
是默认格式化程序,基于 Json.NET,它只是执行 JSON 字符串主体反序列化 (code):
model = jsonSerializer.Deserialize(jsonReader, type);
因为在反序列化过程中对象的构造函数没有被调用,你没有任何错误,比如“必须有一个无参数的构造函数”。
相反,对于 [FromQuery]Something
ComplexTypeModelBinder is used and it first creates an instance of your Something
class by calling default constructor and then assign corresponding values to public properties. Check BindModelCoreAsync method for implementation details。