diff --git a/sample/ODataRoutingSample/Controllers/v1/OrganizationsController.cs b/sample/ODataRoutingSample/Controllers/v1/OrganizationsController.cs index f7ab26325..0bfa6be79 100644 --- a/sample/ODataRoutingSample/Controllers/v1/OrganizationsController.cs +++ b/sample/ODataRoutingSample/Controllers/v1/OrganizationsController.cs @@ -5,6 +5,7 @@ // //------------------------------------------------------------------------------ +using System.Collections.Generic; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.OData.Deltas; using Microsoft.AspNetCore.OData.Formatter; @@ -93,6 +94,74 @@ public IActionResult Patch(DeltaSet changes) return Ok(); } + [HttpPatch] + [EnableQuery] + public IActionResult Patch(int key, Delta delta) + { + /* Send a PATCH request to: http://localhost:5000/v1/Organizations/1 + * using the following payload (v4.01 format, should enable the EnableReadingODataAnnotationWithoutPrefix on ODataSimplifiedOptions) +{ + "Departs@delta": [ + { + "@removed":{"reason":"deleted" }, + "@id":"Departments(13)" + }, + { + "@id":"Departments(42)", + "Name":"Microsoft" + } + ] +} + */ + + // Or using the following payload (v4.0 format) + /* +{ + "Departs@delta": [ + { + "@odata.context":"http://localhost:5000/v1/$metadata#Departments/$deletedEntity", + "id":"Departments(13)", + "reason":"deleted" + }, + { + "@odata.id":"Departments(42)", + "Name":"Microsoft" + } + ] +} + + Be noted: the "id" should go before "reason", otherwise we can't read the "id" value. + It's a bug in ODL side. + */ + + if (delta != null && delta.TryGetPropertyValue("Departs", out object value)) + { + if (value is DeltaSet departs) + { + IList sb = new List(); + foreach (var setItem in departs) + { + if (setItem is IDeltaDeletedResource deletedResource) + { + sb.Add($" |-> A DeletedResource Id = {deletedResource.Id}"); + } + else if (setItem is IDelta deltaResource) + { + sb.Add($" |-> A Delta Resource With ChangedProperties = {string.Join(",", deltaResource.GetChangedPropertyNames())}"); + } + else + { + sb.Add($" |-> Not fully supported: {setItem.Kind}"); + } + } + + return Ok(sb); + } + } + + return Ok(); + } + public IActionResult GetName(int key) { Organization org = new Organization diff --git a/src/Microsoft.AspNetCore.OData/Abstracts/ContainerBuilderExtensions.cs b/src/Microsoft.AspNetCore.OData/Abstracts/ContainerBuilderExtensions.cs index 32fb1f41a..63e742668 100644 --- a/src/Microsoft.AspNetCore.OData/Abstracts/ContainerBuilderExtensions.cs +++ b/src/Microsoft.AspNetCore.OData/Abstracts/ContainerBuilderExtensions.cs @@ -57,6 +57,11 @@ public static IContainerBuilder AddDefaultWebApiServices(this IContainerBuilder MessageQuotas = new ODataMessageQuotas { MaxReceivedMessageSize = Int64.MaxValue }, }); + builder.AddServicePrototype(new ODataSimplifiedOptions + { + EnableReadingODataAnnotationWithoutPrefix = true, + }); + // QueryValidators. builder.AddService(ServiceLifetime.Singleton); diff --git a/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml b/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml index d5a43a42a..8b856e5c4 100644 --- a/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml +++ b/src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml @@ -1102,6 +1102,20 @@ The type to test. True if the type is a DateTime; false otherwise. + + + Determine if a type is a . + + The type to test. + True if the type is a DateOnly; false otherwise. + + + + Determine if a type is a . + + The type to test. + True if the type is a TimeOnly; false otherwise. + Determine if a type is a TimeSpan. diff --git a/test/Microsoft.AspNetCore.OData.Tests/ODataOptionsTests.cs b/test/Microsoft.AspNetCore.OData.Tests/ODataOptionsTests.cs index 5ec4a1b5c..97284f92a 100644 --- a/test/Microsoft.AspNetCore.OData.Tests/ODataOptionsTests.cs +++ b/test/Microsoft.AspNetCore.OData.Tests/ODataOptionsTests.cs @@ -141,7 +141,7 @@ public void AddRouteComponents_WithDependencyInjection_SetModelAndServices() } [Theory] - [InlineData(ODataVersion.V4, false)] + [InlineData(ODataVersion.V4, true)] [InlineData(ODataVersion.V401, true)] public void AddRouteComponents_WithVersionAndDependencyInjection_SetModelAndServices(ODataVersion version, bool readingODataPrefixSetting) {