Applying IfMatch when using a single DateTime as ETag gives an exception
@habbes is already working on this.
Since Jun 6, 2023.
- Dominant language
- C#
- Stars
- 505
- Forks
- 186
- PR merge metrics
- No merged PRs in 30d
Description
Assemblies affected
ASP.NET Core OData 8.2
Describe the bug
Using a DateTime property as ETag will throw the following exception when applying IfMatch.
"The binary operator Equal is not defined for the types 'System.DateTime' and 'System.DateTimeOffset'."
Reproduce steps
The simplest set of steps to reproduce the issue. If possible, reference a commit that demonstrates the issue.
Data Model
public class PieceDto {
Guid id;
string name;
DateTime effectiveStart;
}
EDM (CSDL) Model
EDM model is defined using
var builder = new ODataConventionModelBuilder();
var piece = builder.EntitySet<PieceDto>(ODataRoutes.Pieces).EntityType;
piece.Property(p => p.EffectiveStart).IsConcurrencyToken();
Request/Response
GET response will include a correct etag:
{
"@odata.context": "https://localhost:5003/v1/$metadata#Pieces/$entity",
"@odata.etag": "W/\"MjAyMi0xMi0yMFQyMDo0MzoyNy43Mzg1NDFa\"",
"effectiveStart": "2022-12-20T20:43:27.738541Z",
"id": "6a82a98d-d682-4bd9-a48e-0000094469c5",
}
But in patch method, when applying IfMatch, the exception is raised:
[ETagActionFilter]
public class PiecesODataController : ODataControllerBase
{
[HttpPatch("{id}")]
public async Task<IActionResult> Patch( [FromRoute] Guid id, ODataQueryOptions<PieceDto> options )
{
IQueryable<PieceDto> pieces = await _context.Piece.Where(x => x.Id == id)
.GetQueryAsync(_mapper, options, CreateQuerySettings());
if (pieces.IsEmpty())
{
return NotFound();
}
if (options.IfMatch == null)
{
return StatusCode(StatusCodes.Status412PreconditionFailed);
}
IQueryable<PieceDto> matchedPieces = options.IfMatch.ApplyTo(pieces).Cast<PieceDto>();
.....
}
}
In method DefaultODataEtagHandle.cs:ParseEtag the value retrieved from the etag iss parsed as DateTimeOffset (by ODataUriUtils.ConvertFromUriLiteral).
The exception is raised later when the Linq expression try to compare the original DateTime value to the DateTimeOffset retrieved.
Expected behavior
The value retrieved from the etag should have the same type than the original property used as ConcurrencyCheck.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.