【问题标题】:"The property {property} does not exist on type {type}" - but it does. OData configuration issue?“类型 {type} 上不存在属性 {property}” - 但它确实存在。 OData 配置问题?
【发布时间】:2020-11-30 03:53:34
【问题描述】:

我有一个具有 OData 后端的 Blazor WASM 应用程序。我正在尝试配置我的一个模型的 NavigationProperty,以便我可以使用 $expand= 查询参数返回更多数据,但是在尝试发出 PATCH 请求时我不断收到以下错误(GET 工作正常很好):

Microsoft.OData.ODataException: The property 'JobId' does not exist on type 'Coin.ODataOrderHeader'. Make sure to only use property names that are defined by the type or mark the type as open type.

但它确实存在!不仅在模型中:

public partial class ODataOrderHeader
{
        [Key]
        public int OrderId { get; set; }

        [Column("JobID")]
        [ForeignKey("Job")]
        public int JobId { get; set; }
        ...
        [System.Text.Json.Serialization.JsonPropertyName("Job")]
        public virtual Jobs Job { get; set; }
}

但在$metadata 文档中也是如此:

<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
    <edmx:DataServices>
        <Schema Namespace="Coin" xmlns="http://docs.oasis-open.org/odata/ns/edm">
            ...
            <EntityType Name="ODataOrderHeader">
                <Key>
                    <PropertyRef Name="OrderId" />
                </Key>
                <Property Name="OrderId" Type="Edm.Int32" Nullable="false" />
                <Property Name="JobId" Type="Edm.Int32" />
                ...
                <NavigationProperty Name="Job" Type="Coin.Jobs">
                    <ReferentialConstraint Property="JobId" ReferencedProperty="JobId" />
                </NavigationProperty>
            </EntityType>
            ...
        </Schema>
    </edmx:DataServices>
</edmx:Edmx>

这是创建模型的代码:

        private IEdmModel GetEdmModel()
        {
            var builder = new ODataConventionModelBuilder();
            builder.Namespace = "Coin";
            builder.ContainerName = "CoinContainer";
            ...
            var orders = builder.EntitySet<ODataOrderHeader>("Orders");
            return builder.GetEdmModel();
        }

我应该指出,ODataOrderHeader 更像是 DTO 类型,而 Jobs 是 EF 脚手架类型。

这里是调用 API 的 Simple.OData.Client 代码:

    private async void UpdateItem()
    {
        ODataClient client = new ODataClient(new ODataClientSettings(HttpClient, new Uri("odata", UriKind.Relative)));

        await client.For<ODataOrderHeader>("Orders")
            .Key(currentOrder.OrderId)
            .Set(currentOrder)
            .UpdateEntryAsync();
    }

这是上面代码调用的控制器动作:

        [ODataRoute("/orders({key})")]
        public async Task<IActionResult> Patch([FromODataUri] int key, Delta<ODataOrderHeader> order)
        {
            if (!ModelState.IsValid)
                return BadRequest();

            ...
        }

最后,完整的错误消息:

Unhandled Exception:
Microsoft.OData.ODataException: The property 'JobId' does not exist on type 'Coin.ODataOrderHeader'. Make sure to only use property names that are defined by the type or mark the type as open type.
  at Microsoft.OData.WriterValidationUtils.ValidatePropertyDefined (Microsoft.OData.PropertySerializationInfo propertyInfo, System.Boolean throwOnUndeclaredProperty) <0x61a9028 + 0x00098> in <filename unknown>:0 
  at Microsoft.OData.JsonLight.ODataJsonLightPropertySerializer.WritePropertyInfo (Microsoft.OData.ODataPropertyInfo propertyInfo, Microsoft.OData.Edm.IEdmStructuredType owningType, System.Boolean isTopLevel, Microsoft.OData.IDuplicatePropertyNameChecker duplicatePropertyNameChecker, Microsoft.OData.Evaluation.ODataResourceMetadataBuilder metadataBuilder) <0x6120d78 + 0x000f8> in <filename unknown>:0 
  at Microsoft.OData.JsonLight.ODataJsonLightPropertySerializer.WriteProperty (Microsoft.OData.ODataProperty property, Microsoft.OData.Edm.IEdmStructuredType owningType, System.Boolean isTopLevel, Microsoft.OData.IDuplicatePropertyNameChecker duplicatePropertyNameChecker, Microsoft.OData.Evaluation.ODataResourceMetadataBuilder metadataBuilder) <0x61203e8 + 0x00018> in <filename unknown>:0 
  at Microsoft.OData.JsonLight.ODataJsonLightPropertySerializer.WriteProperties (Microsoft.OData.Edm.IEdmStructuredType owningType, System.Collections.Generic.IEnumerable`1[T] properties, System.Boolean isComplexValue, Microsoft.OData.IDuplicatePropertyNameChecker duplicatePropertyNameChecker, Microsoft.OData.Evaluation.ODataResourceMetadataBuilder metadataBuilder) <0x6011c28 + 0x00048> in <filename unknown>:0 
  at Microsoft.OData.JsonLight.ODataJsonLightWriter.StartResource (Microsoft.OData.ODataResource resource) <0x5ef5478 + 0x003d6> in <filename unknown>:0 
  at Microsoft.OData.ODataWriterCore+<>c__DisplayClass121_0.<WriteStartResourceImplementation>b__0 () <0x5ed80f0 + 0x00082> in <filename unknown>:0 
  at Microsoft.OData.ODataWriterCore.InterceptException (System.Action action) <0x5ed3f20 + 0x00042> in <filename unknown>:0 
  at Microsoft.OData.ODataWriterCore.WriteStartResourceImplementation (Microsoft.OData.ODataResource resource) <0x5ed3a78 + 0x00076> in <filename unknown>:0 
  at Microsoft.OData.ODataWriterCore+<>c__DisplayClass49_0.<WriteStartAsync>b__0 () <0x5ed3628 + 0x0000c> in <filename unknown>:0 
  at Microsoft.OData.TaskUtils.GetTaskForSynchronousOperation (System.Action synchronousOperation) <0x5ed34e0 + 0x0000a> in <filename unknown>:0 
--- End of stack trace from previous location where exception was thrown ---

  at Simple.OData.Client.V4.Adapter.RequestWriter.WriteEntryPropertiesAsync (Microsoft.OData.ODataWriter entryWriter, Microsoft.OData.ODataResource entry, System.Collections.Generic.IDictionary`2[TKey,TValue] links) <0x5ed2260 + 0x000f2> in <filename unknown>:0 
  at Simple.OData.Client.V4.Adapter.RequestWriter.WriteEntryContentAsync (System.String method, System.String collection, System.String commandText, System.Collections.Generic.IDictionary`2[TKey,TValue] entryData, System.Boolean resultRequired) <0x5477750 + 0x0049c> in <filename unknown>:0 
  at Simple.OData.Client.RequestWriterBase.CreateUpdateRequestAsync (System.String collection, System.String entryIdent, System.Collections.Generic.IDictionary`2[TKey,TValue] entryKey, System.Collections.Generic.IDictionary`2[TKey,TValue] entryData, System.Boolean resultRequired) <0x5814b98 + 0x0020c> in <filename unknown>:0 
  at Simple.OData.Client.RequestBuilder.UpdateRequestAsync (System.Boolean resultRequired, System.Threading.CancellationToken cancellationToken) <0x577cd28 + 0x00386> in <filename unknown>:0 
  at Simple.OData.Client.ODataClient.UpdateEntryAsync (Simple.OData.Client.FluentCommand command, System.Boolean resultRequired, System.Threading.CancellationToken cancellationToken) <0x577bcc8 + 0x00162> in <filename unknown>:0 
  at Simple.OData.Client.BoundClient`1[T].UpdateEntryAsync (System.Boolean resultRequired, System.Threading.CancellationToken cancellationToken) <0x576d9a0 + 0x00230> in <filename unknown>:0 
  at Coin.Client.Pages.OrderEdit.UpdateItem () [0x000ac] in C:\Users\trichardson\source\Workspaces\Corsi\COIN2\Client\Pages\OrderEdit.razor:393 
  at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__7_1 (System.Object state) <0x6547930 + 0x0000c> in <filename unknown>:0 
  at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context (System.Object state) <0x65478e0 + 0x00022> in <filename unknown>:0 
  at System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) <0x3112fc8 + 0x00100> in <filename unknown>:0 
  at System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) <0x310b7d8 + 0x00010> in <filename unknown>:0 
  at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem () <0x5743290 + 0x00038> in <filename unknown>:0 
  at System.Threading.ThreadPoolWorkQueue.Dispatch () <0x39a89b8 + 0x00102> in <filename unknown>:0 
  at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback () <0x39a4578 + 0x00000> in <filename unknown>:0 
[ERROR] FATAL UNHANDLED EXCEPTION: Microsoft.OData.ODataException: The property 'JobId' does not exist on type 'Coin.ODataOrderHeader'. Make sure to only use property names that are defined by the type or mark the type as open type.
  at Microsoft.OData.WriterValidationUtils.ValidatePropertyDefined (Microsoft.OData.PropertySerializationInfo propertyInfo, System.Boolean throwOnUndeclaredProperty) <0x61a9028 + 0x00098> in <filename unknown>:0 
  at Microsoft.OData.JsonLight.ODataJsonLightPropertySerializer.WritePropertyInfo (Microsoft.OData.ODataPropertyInfo propertyInfo, Microsoft.OData.Edm.IEdmStructuredType owningType, System.Boolean isTopLevel, Microsoft.OData.IDuplicatePropertyNameChecker duplicatePropertyNameChecker, Microsoft.OData.Evaluation.ODataResourceMetadataBuilder metadataBuilder) <0x6120d78 + 0x000f8> in <filename unknown>:0 
  at Microsoft.OData.JsonLight.ODataJsonLightPropertySerializer.WriteProperty (Microsoft.OData.ODataProperty property, Microsoft.OData.Edm.IEdmStructuredType owningType, System.Boolean isTopLevel, Microsoft.OData.IDuplicatePropertyNameChecker duplicatePropertyNameChecker, Microsoft.OData.Evaluation.ODataResourceMetadataBuilder metadataBuilder) <0x61203e8 + 0x00018> in <filename unknown>:0 
  at Microsoft.OData.JsonLight.ODataJsonLightPropertySerializer.WriteProperties (Microsoft.OData.Edm.IEdmStructuredType owningType, System.Collections.Generic.IEnumerable`1[T] properties, System.Boolean isComplexValue, Microsoft.OData.IDuplicatePropertyNameChecker duplicatePropertyNameChecker, Microsoft.OData.Evaluation.ODataResourceMetadataBuilder metadataBuilder) <0x6011c28 + 0x00048> in <filename unknown>:0 
  at Microsoft.OData.JsonLight.ODataJsonLightWriter.StartResource (Microsoft.OData.ODataResource resource) <0x5ef5478 + 0x003d6> in <filename unknown>:0 
  at Microsoft.OData.ODataWriterCore+<>c__DisplayClass121_0.<WriteStartResourceImplementation>b__0 () <0x5ed80f0 + 0x00082> in <filename unknown>:0 
  at Microsoft.OData.ODataWriterCore.InterceptException (System.Action action) <0x5ed3f20 + 0x00042> in <filename unknown>:0 
  at Microsoft.OData.ODataWriterCore.WriteStartResourceImplementation (Microsoft.OData.ODataResource resource) <0x5ed3a78 + 0x00076> in <filename unknown>:0 
  at Microsoft.OData.ODataWriterCore+<>c__DisplayClass49_0.<WriteStartAsync>b__0 () <0x5ed3628 + 0x0000c> in <filename unknown>:0 
  at Microsoft.OData.TaskUtils.GetTaskForSynchronousOperation (System.Action synchronousOperation) <0x5ed34e0 + 0x0000a> in <filename unknown>:0 
--- End of stack trace from previous location where exception was thrown ---

  at Simple.OData.Client.V4.Adapter.RequestWriter.WriteEntryPropertiesAsync (Microsoft.OData.ODataWriter entryWriter, Microsoft.OData.ODataResource entry, System.Collections.Generic.IDictionary`2[TKey,TValue] links) <0x5ed2260 + 0x000f2> in <filename unknown>:0 
  at Simple.OData.Client.V4.Adapter.RequestWriter.WriteEntryContentAsync (System.String method, System.String collection, System.String commandText, System.Collections.Generic.IDictionary`2[TKey,TValue] entryData, System.Boolean resultRequired) <0x5477750 + 0x0049c> in <filename unknown>:0 
  at Simple.OData.Client.RequestWriterBase.CreateUpdateRequestAsync (System.String collection, System.String entryIdent, System.Collections.Generic.IDictionary`2[TKey,TValue] entryKey, System.Collections.Generic.IDictionary`2[TKey,TValue] entryData, System.Boolean resultRequired) <0x5814b98 + 0x0020c> in <filename unknown>:0 
  at Simple.OData.Client.RequestBuilder.UpdateRequestAsync (System.Boolean resultRequired, System.Threading.CancellationToken cancellationToken) <0x577cd28 + 0x00386> in <filename unknown>:0 
  at Simple.OData.Client.ODataClient.UpdateEntryAsync (Simple.OData.Client.FluentCommand command, System.Boolean resultRequired, System.Threading.CancellationToken cancellationToken) <0x577bcc8 + 0x00162> in <filename unknown>:0 
  at Simple.OData.Client.BoundClient`1[T].UpdateEntryAsync (System.Boolean resultRequired, System.Threading.CancellationToken cancellationToken) <0x576d9a0 + 0x00230> in <filename unknown>:0 
  at Coin.Client.Pages.OrderEdit.UpdateItem () [0x000ac] in C:\Users\trichardson\source\Workspaces\Corsi\COIN2\Client\Pages\OrderEdit.razor:393 
  at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__7_1 (System.Object state) <0x6547930 + 0x0000c> in <filename unknown>:0 
  at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context (System.Object state) <0x65478e0 + 0x00022> in <filename unknown>:0 
  at System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) <0x3112fc8 + 0x00100> in <filename unknown>:0 
  at System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) <0x310b7d8 + 0x00010> in <filename unknown>:0 
  at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem () <0x5743290 + 0x00038> in <filename unknown>:0 
  at System.Threading.ThreadPoolWorkQueue.Dispatch () <0x39a89b8 + 0x00102> in <filename unknown>:0 
  at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback () <0x39a4578 + 0x00000> in <filename unknown>:0 
Uncaught ExitStatusThe program '' has exited with code -1 (0xffffffff).

是我遗漏了配置错误还是控制器操作有问题?

【问题讨论】:

  • 可以区分大小写吗?尝试将[Column("JobID")] 更改为[Column("JobId")]
  • @GuruStron 我希望。数据库中的列是“JobID”,但应用程序的功能完全相同,完全没有该注释。

标签: c# .net-core odata blazor simple.odata.client


【解决方案1】:

对于将来偶然发现此问题的任何人,我能够发现更多信息。

首先,通过在我的 Jobs 类中添加一些数据注释 [IgnoreDataMember] 并在实例化 ODataClient 时添加 {IgnoreUnmappedProperties = true},我能够得到不同的错误。类似于:The key 'JobId' does not exist in the dictionary

对于上下文,我正在尝试执行 OData 所指的 "deep update"。我想在更新父实体的同时更新子实体。但是,Simple.OData.Client 不支持深度更新或深度链接或深度创建。 Here's a 5 year old question from Simple.OData.Client's GitHub page that talks about this 不幸的是,这个包的开发似乎已经停止("Future of Simple.OData.Client""Project Dead?")。由于它不支持“深度更新”,它不知道如何生成请求 URL,这就是我的 PATCH 请求失败的原因。

【讨论】:

  • 也许还有一种方法可以从 Simple.OData.Client 中“强制”正确的 URL 和格式。有人可以证明我错了!
  • 非常感谢您的回答,它拯救了我的夜晚!
猜你喜欢
  • 1970-01-01
  • 2021-06-16
  • 2021-09-25
  • 2021-12-20
  • 1970-01-01
  • 2019-03-23
  • 2020-09-15
  • 1970-01-01
  • 2017-06-06
相关资源
最近更新 更多