【问题标题】:ASP.NET Core Web API - Parameter binding does not work when member of a class is list of InterfaceASP.NET Core Web API - 当类的成员是接口列表时,参数绑定不起作用
【发布时间】:2020-04-27 10:16:26
【问题描述】:
public async Task<IActionResult> AddProjectDetail(ProjectViewModel project)
{
//
}    

public class ProjectViewModel : IProjectViewModel
        {
           public string Id { get; set; }
           public IKeyValue UOPSegment { get; set; } = new KeyValue();
           public IList<IProjectGateAssocViewModel> ProjectGates { get; set; } //Data is not getting binded here
        }

    public interface IProjectViewModel : IBaseDBModel
        {
            string Id { get; set; }
            IKeyValue UOPSegment { get; set; }
            IList<IProjectGateAssocViewModel> ProjectGates { get; set; }
        }

    public interface IProjectGateAssocViewModel 
        {
            string GateCode { get; set; }
            string GateDate { get; set; }
            string ProjectId { get; set; }
        }
    
    public class ProjectGateAssocViewModel : IProjectGateAssocViewModel
        {
            public string GateCode { get; set; }
            public string GateDate { get; set; }
            public string ProjectId { get; set; }
        }

// public IList ProjectGates { get;放; }

这里的数据没有被绑定。 当我尝试调用 API 时出现以下错误:

{ "projectFiles[0].contentType": [ “输入无效。” ] }

【问题讨论】:

    标签: class asp.net-core interface asp.net-core-webapi


    【解决方案1】:

    问题是您期望 ASP.NET Core 绑定能够实例化接口对象。这是不可能的。或者您期望 ASP.NET Core 绑定能够猜测您希望为给定接口实例化的类型。这是可能的,但恐怕它从来没有人认为是有效的绑定方案。

    要了解绑定的问题,您需要知道它是如何工作的。 Binding 能够绑定简单类型、具有公共无参数构造函数和可写属性、集合和字典的复杂类型。

    简单类型 (Docs)

    模型绑定器可以将源字符串转换成的简单类型包括:

    Boolean, Byte, SByte, Char, DateTime, DateTimeOffset, Decimal, Double, Enum, Int32, @98654336@, @987654336 、Int64SingleTimeSpanUInt16UInt32UInt64UriVersion

    复杂类型 (Docs)

    复杂类型必须具有公共默认构造函数和公共可写属性才能绑定。发生模型绑定时,将使用公共默认构造函数实例化该类。

    对于复杂类型的每个属性,模型绑定会在源中查找名称模式 prefix.property_name。如果没有找到,它只查找不带前缀的 property_name。

    对于绑定到参数,前缀是参数名称。对于绑定到 PageModel 公共属性,前缀是公共属性名称。某些属性具有 Prefix 属性,可让您覆盖参数或属性名称的默认用法。

    收藏 (Docs)

    对于简单类型集合的目标,模型绑定会查找参数名称或属性名称的匹配项。如果未找到匹配项,则查找其中一种不带前缀的受支持格式。

    字典 (Docs)

    对于字典目标,模型绑定会查找参数名称或属性名称的匹配项。如果未找到匹配项,则查找其中一种不带前缀的受支持格式。

    附加内容(未记录)

    到目前为止,ASP.NET Core 绑定非常好,能够为您绑定到 IEnumerable&lt;T&gt;IDictionary&lt;TKey, TValue&gt;

    选项 1

    避免绑定到接口。你会省去很多麻烦。

    public class ProjectViewModel : IProjectViewModel
    {
        public string Id { get; set; }
        public IList<ProjectGateAssocViewModel> ProjectGates { get; set; } //Data are getting binded here now
    }
    
    public interface IProjectViewModel
    {
        string Id { get; set; }
        IList<ProjectGateAssocViewModel> ProjectGates { get; set; }
    }
    public interface IProjectGateAssocViewModel
    {
        string GateCode { get; set; }
        string GateDate { get; set; }
        string ProjectId { get; set; }
    }
    
    public class ProjectGateAssocViewModel : IProjectGateAssocViewModel
    {
        public string GateCode { get; set; }
        public string GateDate { get; set; }
        public string ProjectId { get; set; }
    
    }
    

    选项 2

    实现自定义绑定器、自定义类型转换器或自定义格式化程序,因为您需要先实例化对象。

    很难说您应该使用哪种方法,因为这取决于您提出的请求以及这些请求的处理方式。

    【讨论】:

      猜你喜欢
      • 2016-09-03
      • 1970-01-01
      • 1970-01-01
      • 2018-11-09
      • 1970-01-01
      • 2013-06-11
      • 1970-01-01
      • 1970-01-01
      • 2019-04-30
      相关资源
      最近更新 更多