diff --git a/src/Service.Tests/SqlTests/RestApiTests/Patch/PatchApiTestBase.cs b/src/Service.Tests/SqlTests/RestApiTests/Patch/PatchApiTestBase.cs
index 90e132a652..084ef16588 100644
--- a/src/Service.Tests/SqlTests/RestApiTests/Patch/PatchApiTestBase.cs
+++ b/src/Service.Tests/SqlTests/RestApiTests/Patch/PatchApiTestBase.cs
@@ -485,6 +485,37 @@ await SetupAndRunRestApiTest(
);
}
+ ///
+ /// Tests that a PATCH request with an invalid If-Match header value
+ /// (anything other than "*") returns a 400 Bad Request response
+ /// because ETags are not supported.
+ ///
+ [TestMethod]
+ public virtual async Task PatchOne_Update_InvalidIfMatchHeader_Returns400_Test()
+ {
+ Dictionary headerDictionary = new();
+ headerDictionary.Add("If-Match", "\"abc123\"");
+ string requestBody = @"
+ {
+ ""title"": ""The Hobbit Returns to The Shire"",
+ ""publisher_id"": 1234
+ }";
+
+ await SetupAndRunRestApiTest(
+ primaryKeyRoute: "id/1",
+ queryString: null,
+ entityNameOrPath: _integrationEntityName,
+ sqlQuery: string.Empty,
+ operationType: EntityActionOperation.UpsertIncremental,
+ headers: new HeaderDictionary(headerDictionary),
+ requestBody: requestBody,
+ exceptionExpected: true,
+ expectedErrorMessage: "Etags not supported, use '*'",
+ expectedStatusCode: HttpStatusCode.BadRequest,
+ expectedSubStatusCode: DataApiBuilderException.SubStatusCodes.BadRequest.ToString()
+ );
+ }
+
///
/// Test to validate successful execution of PATCH operation which satisfies the database policy for the update operation it resolves into.
///
diff --git a/src/Service.Tests/SqlTests/RestApiTests/Put/PutApiTestBase.cs b/src/Service.Tests/SqlTests/RestApiTests/Put/PutApiTestBase.cs
index 5ee3654897..9989eac099 100644
--- a/src/Service.Tests/SqlTests/RestApiTests/Put/PutApiTestBase.cs
+++ b/src/Service.Tests/SqlTests/RestApiTests/Put/PutApiTestBase.cs
@@ -1114,6 +1114,37 @@ await SetupAndRunRestApiTest(
);
}
+ ///
+ /// Tests that a PUT request with an invalid If-Match header value
+ /// (anything other than "*") returns a 400 Bad Request response
+ /// because ETags are not supported.
+ ///
+ [TestMethod]
+ public virtual async Task PutOne_Update_InvalidIfMatchHeader_Returns400_Test()
+ {
+ Dictionary headerDictionary = new();
+ headerDictionary.Add("If-Match", "\"abc123\"");
+ string requestBody = @"
+ {
+ ""title"": ""The Return of the King"",
+ ""publisher_id"": 1234
+ }";
+
+ await SetupAndRunRestApiTest(
+ primaryKeyRoute: "id/1",
+ queryString: null,
+ entityNameOrPath: _integrationEntityName,
+ sqlQuery: string.Empty,
+ operationType: EntityActionOperation.Upsert,
+ headers: new HeaderDictionary(headerDictionary),
+ requestBody: requestBody,
+ exceptionExpected: true,
+ expectedErrorMessage: "Etags not supported, use '*'",
+ expectedStatusCode: HttpStatusCode.BadRequest,
+ expectedSubStatusCode: DataApiBuilderException.SubStatusCodes.BadRequest.ToString()
+ );
+ }
+
///
/// Tests that a PUT request with If-Match header (strict update semantics)
/// still requires a primary key route. When If-Match is present, the operation
diff --git a/src/Service/Controllers/RestController.cs b/src/Service/Controllers/RestController.cs
index 48a1b98e49..2fadc636d0 100644
--- a/src/Service/Controllers/RestController.cs
+++ b/src/Service/Controllers/RestController.cs
@@ -161,7 +161,7 @@ public async Task Upsert(
{
return await HandleOperation(
route,
- DeterminePatchPutSemantics(EntityActionOperation.Upsert));
+ EntityActionOperation.Upsert);
}
///
@@ -181,7 +181,7 @@ public async Task UpsertIncremental(
{
return await HandleOperation(
route,
- DeterminePatchPutSemantics(EntityActionOperation.UpsertIncremental));
+ EntityActionOperation.UpsertIncremental);
}
///
@@ -206,6 +206,11 @@ private async Task HandleOperation(
{
TelemetryMetricsHelper.IncrementActiveRequests(ApiType.REST);
+ if (operationType is EntityActionOperation.Upsert or EntityActionOperation.UpsertIncremental)
+ {
+ operationType = DeterminePatchPutSemantics(operationType);
+ }
+
if (activity is not null)
{
activity.TrackMainControllerActivityStarted(