You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Describe the bug
If I have a byte[] RowVersion field and I check for and apply queryOptions.ifNoneMatch.ApplyTo, the query remains unaffected and therefore doesn't filter out the records that do match.
Reproduce steps
Let's modify minimally following E2E test already exists: Microsoft.AspNetCore.OData.E2E.Tests.ETags.CRUDWithIfMatchETagsTest.GetEntityWithIfNoneMatchShouldReturnNotModifiedETagsTest
In the ETagsModel file, on Line 40 change the type of the field StringWithConcurrencyCheckAttributeProperty from string to byte[]
Then, in EtagsController, in the Helpers.CreateCustomer method on line 180, initialize this field as the following: StringWithConcurrencyCheckAttributeProperty = new byte[] {0, 0, 0, 0, 0, 0, 16, 28},
a. In case you're afraid of some of the other concurrency fields affecting this, feel free to go to the CRUDWithIfMatchETagsTest.GetEdmModel method and comment out lines 43 and 44 so there's only one concurrency field.
Now, if you run this test, it will fail. If you debug further, you'll notice that the queryOptions.ifNoneMatch.ApplyTo call in EtagsController has absolutely no effect on appliedCustomers
Data Model
public class ETagsCustomer
{
public int Id { get; set; }
public string Name { get; set; }
TRUNCATED SOME FIELDS THAT DON'T AFFECT THIS CASE
[ConcurrencyCheck]
public byte[] StringWithConcurrencyCheckAttributeProperty { get; set; }
public ETagsCustomer RelatedCustomer { get; set; }
[Contained]
public ETagsCustomer ContainedCustomer { get; set; }
}
EDM (CSDL) Model
This example involves using the existing E2E Etags test so I'm not sure how to extract metadata from there without complicating things but here's the code that generates the EDM Model, copy-pasted shamelessly from the file.
I commented out those two lines to isolate the problem. The bug can be recreated regardless of the existence of these lines.
Request/Response
Again, I'm gonna have to copy code. It's really just the GetEntityWithIfNoneMatchShouldReturnNotModifiedETagsTest
Click me
public async Task GetEntityWithIfNoneMatchShouldReturnNotModifiedETagsTest()
{
// Arrange
HttpClient client = CreateClient();
string eTag;
// DeleteUpdatedEntryWithIfMatchETagsTests will change #"0" customer
// PutUpdatedEntryWithIfMatchETagsTests will change #"1"customer
// PatchUpdatedEntryWithIfMatchETagsTest will change #"2" customer
// So, this case uses "4"
int customerId = 4;
var getUri = "odata/ETagsCustomers?$format=json";
// Act
using (var response = await client.GetAsync(getUri))
{
// Assert
Assert.True(response.IsSuccessStatusCode);
var json = await response.Content.ReadAsObject<JObject>();
var result = json.GetValue("value") as JArray;
Assert.NotNull(result);
eTag = result[customerId]["@odata.etag"].ToString();
Assert.False(string.IsNullOrEmpty(eTag));
}
// Arrange & Act
var getRequestWithEtag = new HttpRequestMessage(HttpMethod.Get, $"odata/ETagsCustomers({customerId})");
getRequestWithEtag.Headers.IfNoneMatch.ParseAdd(eTag);
using (var response = await client.SendAsync(getRequestWithEtag))
{
// Assert
Assert.Equal(HttpStatusCode.NotModified, response.StatusCode);
}
}
Expected behavior
This test should pass. Since this field is never changed.
Screenshots
N/A
Additional context
In order of importance:
I have been debugging this for a while and here's the only useful observation I have made:
In Microsoft.AspNetCore.OData.Query.ETag, on line 148, if we remove the following block:
if (IsIfNoneMatch)
{
where = Expression.Not(where);
}
It does send back a 304 Not Modified and does pass the test.
I first discovered this while working on my project. I was using this test as a reference to make sure I was using etags correctly. After failing to purposefully produce a 304 Not Modified response by passing in an If-None-Match header, I decided to see if using a byte[] field makes the E2E test fail. And I was right.
The text was updated successfully, but these errors were encountered:
Assemblies affected
ASP.NET Core OData 8.x
Describe the bug
If I have a
byte[] RowVersion
field and I check for and applyqueryOptions.ifNoneMatch.ApplyTo
, the query remains unaffected and therefore doesn't filter out the records that do match.Reproduce steps
Let's modify minimally following E2E test already exists:
Microsoft.AspNetCore.OData.E2E.Tests.ETags.CRUDWithIfMatchETagsTest.GetEntityWithIfNoneMatchShouldReturnNotModifiedETagsTest
In the
ETagsModel
file, onLine 40
change the type of the fieldStringWithConcurrencyCheckAttributeProperty
fromstring
tobyte[]
Then, in
EtagsController
, in theHelpers.CreateCustomer
method online 180
, initialize this field as the following:StringWithConcurrencyCheckAttributeProperty = new byte[] {0, 0, 0, 0, 0, 0, 16, 28},
a. In case you're afraid of some of the other concurrency fields affecting this, feel free to go to the
CRUDWithIfMatchETagsTest.GetEdmModel
method and comment outlines 43 and 44
so there's only one concurrency field.Now, if you run this test, it will fail. If you debug further, you'll notice that the
queryOptions.ifNoneMatch.ApplyTo
call inEtagsController
has absolutely no effect onappliedCustomers
Data Model
EDM (CSDL) Model
This example involves using the existing E2E Etags test so I'm not sure how to extract metadata from there without complicating things but here's the code that generates the EDM Model, copy-pasted shamelessly from the file.
I commented out those two lines to isolate the problem. The bug can be recreated regardless of the existence of these lines.
Request/Response
Again, I'm gonna have to copy code. It's really just the
GetEntityWithIfNoneMatchShouldReturnNotModifiedETagsTest
Click me
Expected behavior
This test should pass. Since this field is never changed.
Screenshots
N/A
Additional context
In order of importance:
In
Microsoft.AspNetCore.OData.Query.ETag
, online 148
, if we remove the following block:It does send back a
304 Not Modified
and does pass the test.304 Not Modified
response by passing in an If-None-Match header, I decided to see if using abyte[]
field makes the E2E test fail. And I was right.The text was updated successfully, but these errors were encountered: