Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -94,18 +94,30 @@ public static string GetString(this IEdmRecordExpression record, string property
/// <param name="propertyName">The property name.</param>
/// <returns>The Enum value or null.</returns>
public static T? GetEnum<T>(this IEdmRecordExpression record, string propertyName)
where T : struct
where T : struct, Enum
{
Utils.CheckArgumentNull(record, nameof(record));
Utils.CheckArgumentNull(propertyName, nameof(propertyName));

return (record.Properties?.FirstOrDefault(e => propertyName.Equals(e.Name, StringComparison.Ordinal)) is IEdmPropertyConstructor property &&
if (record.Properties?.FirstOrDefault(e => propertyName.Equals(e.Name, StringComparison.Ordinal))
is IEdmPropertyConstructor property &&
property.Value is IEdmEnumMemberExpression value &&
value.EnumMembers != null &&
value.EnumMembers.Any() &&
Enum.TryParse(value.EnumMembers.First().Name, out T result)) ?
result :
null;
value.EnumMembers.Any())
{
long combinedValue = 0;
foreach (var enumMember in value.EnumMembers)
{
if (Enum.TryParse(enumMember.Name, out T enumValue))
{
combinedValue |= Convert.ToInt64(enumValue);
}
}

return (T)Enum.ToObject(typeof(T), combinedValue);
}

return null;
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,16 @@
<TargetFrameworks>net8.0</TargetFrameworks>
<PackageId>Microsoft.OpenApi.OData</PackageId>
<SignAssembly>true</SignAssembly>
<Version>2.0.0-preview.1</Version>
<Version>2.0.0-preview.2</Version>
<Description>This package contains the codes you need to convert OData CSDL to Open API Document of Model.</Description>
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
<PackageTags>Microsoft OpenApi OData EDM</PackageTags>
<RepositoryUrl>https://github.com/Microsoft/OpenAPI.NET.OData</RepositoryUrl>
<PackageReleaseNotes>
- Upgraded to Microsoft.Odata.Edm 8.0.0
- Cleaned up obsolete APIs
- Changed target framework to net8.0
- Cleaned up obsolete APIs
- Changed target framework to net8.0
- Adds support for retrieving collection of enum values from UpdateMethod property of UpdateRestrictions annotation #564
</PackageReleaseNotes>
<AssemblyName>Microsoft.OpenApi.OData.Reader</AssemblyName>
<AssemblyOriginatorKeyFile>..\..\tool\Microsoft.OpenApi.OData.snk</AssemblyOriginatorKeyFile>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,12 @@ public void AddUpdateOperation(OpenApiPathItem item)
if ((Context.Settings.RequireRestrictionAnnotationsToGenerateComplexPropertyPaths && isUpdatable) ||
!Context.Settings.RequireRestrictionAnnotationsToGenerateComplexPropertyPaths)
{
if (updateRestrictions != null && updateRestrictions.IsUpdateMethodPut)
if (updateRestrictions?.IsUpdateMethodPutAndPatch == true)
{
AddOperation(item, OperationType.Put);
AddOperation(item, OperationType.Patch);
}
else if (updateRestrictions?.IsUpdateMethodPut == true)
{
AddOperation(item, OperationType.Put);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,12 @@ protected override void SetOperations(OpenApiPathItem item)
updateRestrictions ??= entityUpdateRestrictions;
if (updateRestrictions?.IsUpdatable ?? true)
{
if (updateRestrictions != null && updateRestrictions.IsUpdateMethodPut)
if (updateRestrictions?.IsUpdateMethodPutAndPatch == true)
{
AddOperation(item, OperationType.Put);
AddOperation(item, OperationType.Patch);
}
else if (updateRestrictions?.IsUpdateMethodPut == true)
{
AddOperation(item, OperationType.Put);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,17 +243,23 @@ private void AddDeleteOperation(OpenApiPathItem item, NavigationPropertyRestrict

private void AddUpdateOperation(OpenApiPathItem item, UpdateRestrictionsType updateRestrictionsType)
{
if (updateRestrictionsType == null || updateRestrictionsType.IsUpdatable)
{
if (updateRestrictionsType != null && updateRestrictionsType.IsUpdateMethodPut)
{
AddOperation(item, OperationType.Put);
}
else
{
AddOperation(item, OperationType.Patch);
}
}
if (updateRestrictionsType?.IsUpdatable ?? true)
{
if (updateRestrictionsType?.IsUpdateMethodPutAndPatch == true)
{
AddOperation(item, OperationType.Put);
AddOperation(item, OperationType.Patch);
}
else if (updateRestrictionsType?.IsUpdateMethodPut == true)
{
AddOperation(item, OperationType.Put);
}
else
{
AddOperation(item, OperationType.Patch);
}
}

}

/// <inheritdoc/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// ------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.OData.Edm.Vocabularies;
Expand All @@ -14,17 +15,18 @@ namespace Microsoft.OpenApi.OData.Vocabulary.Capabilities
/// <summary>
/// Enumerates HTTP methods that can be used to update entities
/// </summary>
[Flags]
internal enum HttpMethod
{
/// <summary>
/// The HTTP PATCH Method
/// </summary>
PATCH,
PATCH = 1,

/// <summary>
/// The HTTP PUT Method
/// </summary>
PUT
PUT = 2
}
/// <summary>
/// Complex Type: Org.OData.Capabilities.V1.UpdateRestrictionsType
Expand All @@ -46,10 +48,10 @@ internal class UpdateRestrictionsType : IRecord
/// <summary>
/// Gets the value indicating Entities can be inserted, updated, and deleted via a PATCH request with a delta payload.
/// </summary>
public bool? DeltaUpdateSupported { get; private set; }

public bool? DeltaUpdateSupported { get; private set; }
/// <summary>
/// Gets the value indicating the HTTP Method (PUT or PATCH) for updating an entity.
/// Gets the values indicating the HTTP Method (PUT and/or PATCH) for updating an entity.
/// If null, PATCH should be supported and PUT MAY be supported.
/// </summary>
public HttpMethod? UpdateMethod { get; private set; }
Expand Down Expand Up @@ -124,10 +126,16 @@ public bool IsNonUpdatableNavigationProperty(string navigationPropertyPath)
}

/// <summary>
/// Tests whether the update method for the entity has been explicitly specified as PUT
/// Tests whether the update method for the target has been explicitly specified as PUT
/// </summary>
public bool IsUpdateMethodPut => UpdateMethod.HasValue && UpdateMethod.Value == HttpMethod.PUT;

/// <summary>
/// Tests whether the update method for the target has been explicitly specified as PATCH and PUT
/// </summary>
public bool IsUpdateMethodPutAndPatch => UpdateMethod.HasValue &&
(UpdateMethod.Value & (HttpMethod.PUT | HttpMethod.PATCH)) == (HttpMethod.PUT | HttpMethod.PATCH);

/// <summary>
/// Lists the media types acceptable for the request content
/// </summary>
Expand Down Expand Up @@ -157,7 +165,7 @@ public void Initialize(IEdmRecordExpression record)
// DeltaUpdateSupported
DeltaUpdateSupported = record.GetBoolean("DeltaUpdateSupported");

// UpdateMethod
// UpdateMethod
UpdateMethod = record.GetEnum<HttpMethod>("UpdateMethod");

// FilterSegmentSupported
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,7 @@ public void CreatePathItemForNavigationPropertyAndUpdateMethodUpdateRestrictions
<PropertyValue Property=""UpdateRestrictions"" >
<Record>
<PropertyValue Property=""UpdateMethod"">
<EnumMember>Org.OData.Capabilities.V1.HttpMethod/PUT</EnumMember>
<EnumMember>Org.OData.Capabilities.V1.HttpMethod/PUT Org.OData.Capabilities.V1.HttpMethod/PATCH </EnumMember>
</PropertyValue>
<PropertyValue Property=""Updatable"" Bool=""{1}"" />
</Record>
Expand Down Expand Up @@ -488,21 +488,21 @@ public void CreatePathItemForNavigationPropertyAndUpdateMethodUpdateRestrictions
if (isContainment)
{
expected = updatable
? (new[] { OperationType.Get, OperationType.Put, OperationType.Delete })
: (new[] { OperationType.Get, OperationType.Delete });
? ([OperationType.Get, OperationType.Put, OperationType.Patch, OperationType.Delete])
: ([OperationType.Get, OperationType.Delete]);
}
else
{
expected = updatable
? (new[] { OperationType.Get, OperationType.Put })
: (new[] { OperationType.Get });
? ([OperationType.Get, OperationType.Put, OperationType.Patch,])
: ([OperationType.Get]);
}
}
else
{
expected = isContainment
? (new[] { OperationType.Get, OperationType.Patch, OperationType.Delete })
: (new[] { OperationType.Get });
? ([OperationType.Get, OperationType.Patch, OperationType.Delete])
: ([OperationType.Get]);

}

Expand Down