C# 到ASP.NET Core 2.2控制器的邮递员表单数据未绑定到具有专用setter的命令
工具C# 到ASP.NET Core 2.2控制器的邮递员表单数据未绑定到具有专用setter的命令,c#,asp.net-core,postman,C#,Asp.net Core,Postman,工具 Visual Studio 2017 ASP.NET核心2.2 邮递员v7.2.0 我想做的事 将FormData从Postman发送到ASP.NET核心控制器,并将请求中的数据绑定到具有私有setter属性的命令类 我使用相同的设置(私有setter)发送了JSON数据,没有问题。FromBody属性将JSON字符串反序列化到模型中,没有错误 问题 如果模型具有私有setter,则作为基元类型的属性不会绑定。但是,复杂类型不受访问修饰符的影响 控制器 [HttpPost] [产品响应
- Visual Studio 2017
- ASP.NET核心2.2
- 邮递员v7.2.0
FromBody
属性将JSON字符串反序列化到模型中,没有错误
问题
如果模型具有私有setter,则作为基元类型的属性不会绑定。但是,复杂类型不受访问修饰符的影响
控制器
[HttpPost]
[产品响应类型((int)HttpStatusCode.OK)]
[产品响应类型((int)HttpStatusCode.BadRequest)]
公共异步任务CreateItemAsync([FromForm]CreateItemCommand命令)
{
布尔结果=假;
commandResult=wait\u mediator.Send(命令);
如果(!commandResult)
{
返回请求();
}
返回Ok();
}
命令
注意:Title
属性被特意留给了一个公共setter来说明behviour
[DataContract]
公共类CreateItemCommand
:IRequest
{
[数据成员]
公共字符串标题{get;set;}
[数据成员]
公共字符串说明{get;private set;}
[数据成员]
公共整数计数{get;私有集;}
[数据成员]
公共HashSet标记{get;private set;}
[数据成员]
公共字符串ItemDate{get;private set;}
[数据成员]
公共列表文档{get;private set;}
公共CreateItemCommand()
{
Skills=newhashset();
Systems=新的HashSet();
}
public CreateItemCommand(字符串标题、字符串描述、,
int计数、哈希集标记、字符串itemDate、,
(文件清单)
:此()
{
头衔=头衔;
描述=描述;
计数=计数
标签=标签;
ItemDate=ItemDate;
文件=文件;
}
}
在Postman中,我现在按如下方式设置请求:
我已经混淆了一些信息,但是您可以看到带有私有setter的基本类型没有设置
问题
FromForm
时会发生这种情况,而设置为FromBody
protected virtual object CreateModel(ModelBindingContext bindingContext)
{
if (bindingContext == null)
{
throw new ArgumentNullException(nameof(bindingContext));
}
// If model creator throws an exception, we want to propagate it back up the call stack, since the
// application developer should know that this was an invalid type to try to bind to.
if (_modelCreator == null)
{
// The following check causes the ComplexTypeModelBinder to NOT participate in binding structs as
// reflection does not provide information about the implicit parameterless constructor for a struct.
// This binder would eventually fail to construct an instance of the struct as the Linq's NewExpression
// compile fails to construct it.
var modelTypeInfo = bindingContext.ModelType.GetTypeInfo();
if (modelTypeInfo.IsAbstract || modelTypeInfo.GetConstructor(Type.EmptyTypes) == null)
{
var metadata = bindingContext.ModelMetadata;
switch (metadata.MetadataKind)
{
case ModelMetadataKind.Parameter:
throw new InvalidOperationException(
Resources.FormatComplexTypeModelBinder_NoParameterlessConstructor_ForParameter(
modelTypeInfo.FullName,
metadata.ParameterName));
case ModelMetadataKind.Property:
throw new InvalidOperationException(
Resources.FormatComplexTypeModelBinder_NoParameterlessConstructor_ForProperty(
modelTypeInfo.FullName,
metadata.PropertyName,
bindingContext.ModelMetadata.ContainerType.FullName));
case ModelMetadataKind.Type:
throw new InvalidOperationException(
Resources.FormatComplexTypeModelBinder_NoParameterlessConstructor_ForType(
modelTypeInfo.FullName));
}
}
_modelCreator = Expression
.Lambda<Func<object>>(Expression.New(bindingContext.ModelType))
.Compile();
}
return _modelCreator();
}
受保护的虚拟对象CreateModel(ModelBindingContext)
{
if(bindingContext==null)
{
抛出新ArgumentNullException(nameof(bindingContext));
}
//如果模型创建者抛出异常,我们希望将其传播回调用堆栈,因为
//应用程序开发人员应该知道,尝试绑定到的类型无效。
如果(_modelCreator==null)
{
//以下检查导致ComplexTypeModelBinder不作为成员参与绑定结构
//反射不提供有关结构的隐式无参数构造函数的信息。
//该绑定器最终将无法将结构的实例构造为Linq的NewExpression
//compile无法构造它。
var modelTypeInfo=bindingContext.ModelType.GetTypeInfo();
if(modelTypeInfo.isastract | | modelTypeInfo.GetConstructor(Type.EmptyTypes)==null)
{
var metadata=bindingContext.ModelMetadata;
开关(metadata.MetadataKind)
{
案例模型MetadataKind。参数:
抛出新的InvalidOperationException(
Resources.FormatComplexTypeModelBinder\u NoParameters构造函数\u ForParameter(
modelTypeInfo.FullName,
metadata.ParameterName));
case ModelMetadataKind.Property:
抛出新的InvalidOperationException(
Resources.FormatComplexTypeModelBinder\u NoParameters构造函数\u ForProperty(
modelTypeInfo.FullName,
metadata.PropertyName,
bindingContext.ModelMetadata.ContainerType.FullName));
案例模型MetadataKind。类型:
抛出新的InvalidOperationException(
Resources.FormatComplexTypeModelBinder\u NoParameters构造函数\u ForType(
modelTypeInfo.FullName));
}
}
_modelCreator=表达式
.Lambda(Expression.New(bindingContext.ModelType))
.Compile();
}
返回_modelCreator();
}
为什么参数属性设置为FromForm时会发生这种情况,而设置为FromBody时不会发生这种情况
对于FromBody
,使用JsonInputFormatter
从body请求绑定模型,使用JsonConvert.DeserializeObject
反序列化对象,并支持从Json字符串反序列化包含私有setter的对象