Мне нужно вызвать сервер, который предоставляет действие. Это действие имеет либо строку коллекции сложных типов, либо коллекцию сложных типов в качестве параметров. Мне тоже нужно вызвать.
Метаданные:
или:
<Action Name = "BulkChange" IsBound = "true">
<Parameter Name = "bindingParameter" Type = "Collection(PropertyCore.InspectionDuty)"/>
<Parameter Name = "Comment" Type = "Edm.String" Unicode = "false"/>
<Parameter Name = "Changes" Type = "Collection(PropertyCore.InspectionDutyChange)"/>
</Action>
Со следующим сложным типом:
<ComplexType Name = "InspectionDutyChange">
<Property Name = "Operation" Type = "Operations.Operations" Nullable = "false"/>
<Property Name = "Identity" Type = "Edm.Guid" Nullable = "false"/>
<Property Name = "IsDisabled" Type = "Edm.Boolean" Nullable = "false"/>
<Property Name = "SeriesStart" Type = "Edm.DateTimeOffset"/>
<Property Name = "Interval" Type = "Common.Interval"/>
<NavigationProperty Name = "Module" Type = "PropertyCore.Module"/>
<NavigationProperty Name = "Equipment" Type = "PropertyCore.Equipment"/>
<NavigationProperty Name = "OperatorTask" Type = "PropertyCore.OperatorTask"/>
</ComplexType>
Или, альтернативно:
<Action Name = "BulkChange" IsBound = "true">
<Parameter Name = "bindingParameter" Type = "Collection(PropertyCore.InspectionDuty)"/>
<Parameter Name = "Updates" Type = "PropertyCore.InspectionDutyChanges"/>
</Action>
со сложными типами, определенными как
<ComplexType Name = "InspectionDutyChanges">
<Property Name = "Comment" Type = "Edm.String"/>
<Property Name = "Changes" Type = "Collection(PropertyCore.InspectionDutyChange)"/>
</ComplexType>
<ComplexType Name = "InspectionDutyChange">
<Property Name = "Operation" Type = "Operations.Operations" Nullable = "false"/>
<Property Name = "Identity" Type = "Edm.Guid" Nullable = "false"/>
<Property Name = "IsDisabled" Type = "Edm.Boolean" Nullable = "false"/>
<Property Name = "SeriesStart" Type = "Edm.DateTimeOffset"/>
<Property Name = "Interval" Type = "Common.Interval"/>
<NavigationProperty Name = "Module" Type = "PropertyCore.Module"/>
<NavigationProperty Name = "Equipment" Type = "PropertyCore.Equipment"/>
<NavigationProperty Name = "OperatorTask" Type = "PropertyCore.OperatorTask"/>
</ComplexType>
Я не вижу способа обойти это, поскольку мы должны поддерживать несколько обновлений за один прогон.
Исключения, которые я получил, указывают на серьезные недостатки odata.net.
Первый вариант:
Microsoft.OData.ODataException: Unsupported primitive type.
A primitive type could not be determined for an instance of type 'Api.Odata.InspectionDutyChange'.
Result StackTrace:
at Microsoft.OData.ValidationUtils.ValidateIsExpectedPrimitiveType(Object value,
IEdmPrimitiveTypeReference valuePrimitiveTypeReference,
IEdmTypeReference expectedTypeReference)
at Microsoft.OData.JsonLight.ODataJsonLightValueSerializer.WritePrimitiveValue(Object value,
IEdmTypeReference actualTypeReference,
IEdmTypeReference expectedTypeReference)
at Microsoft.OData.JsonLight.ODataJsonLightCollectionWriter.WriteCollectionItem(Object item,
IEdmTypeReference expectedItemType)
at Microsoft.OData.ODataCollectionWriterCore.InterceptException(Action action)
at Microsoft.OData.TaskUtils.GetTaskForSynchronousOperation(Action synchronousOperation)
--- End of stack trace from previous location where exception was thrown ---
и второй вариант:
Microsoft.OData.ODataException: The parameter 'Updates' is of Edm type kind 'Complex'. You cannot call WriteValue on a parameter that is not of Edm type kinds 'Primitive', 'Enum' or 'Complex'.
Stack trace:
Result StackTrace:
at Microsoft.OData.ODataParameterWriterCore.VerifyCanWriteValueParameter(Boolean synchronousCall, String parameterName, Object parameterValue)
at Microsoft.OData.ODataParameterWriterCore.WriteValueAsync(String parameterName, Object parameterValue)
Я могу найти обходной путь для одного обновления, но в целом это неприменимо.
Мы используем клиент Odata, но это не проблема клиента. Трассировка стека указывает на ограничения в стеке Odata.Net. Что также медленно обновляется. Альтернативы. Мне придется вручную создать HTTP-запрос для этих вызовов.
Обновление: обходного пути нет. Похоже, пока это не будет исправлено в библиотеках Odata.Net, мы должны придерживаться стандартного REST API и вручную создавать полезную нагрузку. Каждый сложный тип терпит неудачу, и я не могу разложить последний уровень, поскольку он содержит свойства навигации. Ссылки не могу перекомпоновать. Я уже использую специальный десериализатор, потому что это еще один сценарий, не поддерживаемый в Odata.Net. Если у кого-то нет обходного пути, это действие совместимо с Odata, но несовместимо с Odata.net.
Я предполагаю, что вы используете Simple.Odata.client
. Эта библиотека не обновлялась с тех пор, как в ядре OData было внесено изменение, чтобы рассматривать сложные типы так же, как типы сущностей, потому что сложные типы имеют свойства навигации так же, как типы сущностей. Описание изменения можно найти здесь: ODataComplexValue Проблема также была решена в проблеме GitHub: Автор коллекций сложных типов. Поэтому я бы посоветовал вам использовать обновленный и работающий Microsoft.OData.Client
.