У меня есть родительский объект с дочерним свойством коллекции сложных объектов. При выполнении POST для создания новой записи этого родителя и связанных с ним дочерних элементов я вижу в действии Post()
, что родитель десериализован правильно, но дочерняя коллекция пуста.
В проекте API используются следующие версии пакетов для веб-API и OData:
Microsoft.AspNet.OData — v7.1.0
Microsoft.AspNet.WebApi — v5.2.7
Примеры моделей:
public class Parent
{
public Parent()
{
Children = new List<Child>();
}
public int Id { get; set; }
public string Name { get; set; }
public List<Child> Children { get; set; }
}
public class Child
{
public int Id { get; set; }
public int ParentId { get; set; }
public string Name { get; set; }
}
Конфигурация OData
public static void Register(HttpConfiguration config)
{
var builder = new ODataConventionModelBuilder();
builder.Namespace = "NS";
builder.EntitySet<Parent>("Parents")
.EntityType
.Expand(SelectExpandType.Automatic)
.Filter().OrderBy().Select().Page();
config.MapODataServiceRoute("ODataRoute", null, builder.GetEdmModel());
}
Определение контроллера
public class ParentsController : ODataController
{
public async Task<IHttpActionResult> Post(Parent model)
{
// process data from 'model' parameter here
}
}
Именно внутри этого действия контроллера Post()
коллекция пуста, т. е. model.Children.Length
равна нулю.
На стороне клиента я использую расширение Генератор клиентского кода OData v4 (v7.5.1) для создания клиентских прокси-классов из метаданных API. В приведенном ниже фрагменте показано, как создаются прокси-объекты и передаются в конечную точку API:
var apiModel = new Parent();
apiModel.Children.Load(new List<Child> { new Child { Name = "Test Child" } })
Container.AddToParents(apiModel);
await Container.SaveChangesAsync();
Я могу подтвердить, что дочерние объекты передаются в API. Просто кажется, что API не десериализует их в коллекцию для параметра действия. Кто-нибудь знает, что может быть причиной этого? Любая помощь будет принята с благодарностью.
Обновлять
Оказывается, дочерняя коллекция на самом деле не была передана. Трафик, который я зафиксировал в Fiddler, показал, что дочерний массив был запущен каким-то ошибочным тестовым кодом в моем клиенте, а не прокси-сервером OData v4 Client Code Generator.
Проблема в том, что прокси-сервер, сгенерированный генератором клиентского кода OData v4, не поддерживает глубокие вставки. Вопрос Этот Stackoverflow.com дал мне правильную терминологию для поиска, так как на него был дан ответ в 2017 году, и я хотел узнать, добавлена ли поддержка. К сожалению, это не так, судя по открытой проблеме это на GitHub команды.
На данный момент единственными вариантами, по-видимому, являются создание родителя, а затем всех дочерних элементов в виде двух отдельных вызовов или переключение на другую библиотеку, например RestSharp.