ASP. NET Базовый веб-API - привязка параметров не работает, когда членом класса является список интерфейса. - PullRequest
0 голосов
/ 09 января 2020
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; }

        }

// publi c IList ProjectGates {get; набор; }

Здесь данные не связываются. Когда я пытаюсь вызвать API, я получаю сообщение об ошибке ниже

{"projectFiles [0] .contentType": ["Ввод был недействительным." ]}

1 Ответ

0 голосов
/ 10 января 2020

Проблема заключается в том, что вы ожидаете, что ASP. NET Связывание с ядром способно создать экземпляр объекта интерфейса. Что не возможно. Или вы ожидаете ASP. NET Базовая привязка способна угадать, какой тип вы хотите создать для данного интерфейса. Это возможно, но я боюсь, что это что-то, что никто никогда не считал допустимым сценарием привязки.

Чтобы понять проблему с привязкой, вам нужно знать, как она работает. Привязка позволяет связывать простые типы, сложные типы с помощью конструктора publi c без параметров и доступных для записи свойств, коллекций и словарей.

Простые типы ( Документы )

Простые типы, в которые механизм связывания может преобразовывать исходные строки, включают следующие:

Boolean, Byte, SByte, Char, DateTime, DateTimeOffset, Decimal, Double, Enum, Guid, Int16, Int32, Int64, Single, TimeSpan, UInt16, UInt32, UInt64, Uri, Version

Сложные типы ( Документы )

Сложный тип должен иметь конструктор по умолчанию publi c и publi c записываемые свойства для привязки. Когда происходит привязка модели, экземпляр класса создается с помощью конструктора по умолчанию publi c.

Для каждого свойства сложного типа привязка модели просматривает источники для шаблона имени prefix.property_name. Если ничего не найдено, он ищет только имя_свойства без префикса.

Для привязки к параметру префиксом является имя параметра. Для привязки к свойству PageModel publi c префиксом является имя свойства publi c. Некоторые атрибуты имеют свойство Prefix, которое позволяет переопределить использование по умолчанию имени параметра или свойства.

Коллекции ( Документы )

Для целей, которые являются коллекциями простых типов, привязка модели ищет совпадения с параметром_имя или имя_свойства. Если совпадений не найдено, он ищет один из поддерживаемых форматов без префикса.

Словари ( Документы )

Для словарных целей: привязка модели ищет совпадения с параметром_имя или имя_свойства. Если совпадений не найдено, он ищет один из поддерживаемых форматов без префикса.

Дополнительно (не документировано)

Пока ASP. NET Базовое связывание - это то хорошее, что способно связать вас с IEnumerable<T> или IDictionary<TKey, TValue>.

Опция 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

Реализация пользовательских подшивок, пользовательских преобразователей типов или пользовательских форматеров ) поскольку вам нужно сначала создать экземпляры объектов.

Трудно сказать, какой метод следует использовать, поскольку это зависит от запросов, которые вы делаете, и от того, как они обрабатываются.

...