Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// </copyright>
//------------------------------------------------------------------------------

using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.OData.Deltas;
using Microsoft.AspNetCore.OData.Formatter;
Expand Down Expand Up @@ -93,6 +94,74 @@ public IActionResult Patch(DeltaSet<Organization> changes)
return Ok();
}

[HttpPatch]
[EnableQuery]
public IActionResult Patch(int key, Delta<Organization> 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<Department> departs)
{
IList<string> sb = new List<string>();
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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<ICountQueryValidator, CountQueryValidator>(ServiceLifetime.Singleton);

Expand Down
14 changes: 14 additions & 0 deletions src/Microsoft.AspNetCore.OData/Microsoft.AspNetCore.OData.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1102,6 +1102,20 @@
<param name="clrType">The type to test.</param>
<returns>True if the type is a DateTime; false otherwise.</returns>
</member>
<member name="M:Microsoft.AspNetCore.OData.Common.TypeHelper.IsDateOnly(System.Type)">
<summary>
Determine if a type is a <see cref="T:System.DateOnly"/>.
</summary>
<param name="clrType">The type to test.</param>
<returns>True if the type is a DateOnly; false otherwise.</returns>
</member>
<member name="M:Microsoft.AspNetCore.OData.Common.TypeHelper.IsTimeOnly(System.Type)">
<summary>
Determine if a type is a <see cref="T:System.TimeOnly"/>.
</summary>
<param name="clrType">The type to test.</param>
<returns>True if the type is a TimeOnly; false otherwise.</returns>
</member>
<member name="M:Microsoft.AspNetCore.OData.Common.TypeHelper.IsTimeSpan(System.Type)">
<summary>
Determine if a type is a TimeSpan.
Expand Down
2 changes: 1 addition & 1 deletion test/Microsoft.AspNetCore.OData.Tests/ODataOptionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down