我有一个Blazor WASM应用程序,它有一个OData后端。我试图配置我的模型中的NavigationProperty,以便我可以使用
这里是创建模型的代码:
$expand=
查询参数返回更多数据,但是当我尝试进行PATCH
请求时(GET
正常工作),我一直收到以下错误:
Microsoft.OData.ODataException: 属性“JobId”在类型“Coin.ODataOrderHeader”上不存在。确保仅使用类型定义的属性名称或将该类型标记为开放类型。
但实际上它是存在的!不仅仅是在模型中: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")]
。 - Guru Stron