2

Posted a few variations of a theme on this question but don't seem to have asked the right question and have also dug more into my problem.

So...

I am querying Azure Table Storage using the Azure.Data.Table TableClient with the GetEntityAsync<Type>(partitionKey, rowKey) method


Update - TableClient Calling Code

using the following code:

Initialize the tableclient:

public AzureTableService(string tableName, string storageUri, string accountName, string storageAccountKey) 
{
         tableClient  = new TableClient(
         new Uri(storageUri),
         tableName,
         new TableSharedKeyCredential(accountName, storageAccountKey));
}

Get the TableEntity

public async Task<TableEntity> GetEntityAsync(string partitionKey, string rowKey) 
{
        var response = await tableClient.GetEntityAsync<TableEntity>(partitionKey, rowKey);
        return response.Value;
}

in two ways:

  1. With TableEntity as the type
  2. With User as the type

TableEntity is the type Azure.Data.Table.TableEntity which itself inherits Azure.Data.Table.ITableEntity. ITableEntity defines the properties ETag Etag, string PartitionKey, string RowKey, and DateTimeoOffset? Timestamp.

User is a class which inherits from ITableEntity and therefore has those same properties alongside strings for Forename, Surname, Mobile and Address.


Update - User Object Definition

public class User : ITableEntity
{
    public User() { }
    public string PartitionKey { get; set; }
    public string RowKey { get; set; }
    public DateTimeOffset? Timestamp { get; set; }
    public ETag ETag { get; set; }
    public string Forename { get; set; }
    public string Surname { get; set; }
    public string Mobile { get; set; }
    public string Address { get; set; }

}

As such both are valid to use as the type for the method GetEntityAsync<type> as they both implement the same interface.

If I use the User type the returned object serialised as Json is:

{
    "partitionKey": "partitionKey",
    "rowKey": "rowKey",
    "timestamp": "2023-02-09T22:28:54.0242121+00:00",
    "eTag": {},
    "forename": "forename",
    "surname": "surname",
    "mobile": "mobile",
    "address": "address"
}

If I use the TableEntity type the returned object serialised as Json is:

{
    "odata.etag": "W/\"datetime'2023-02-09T22%3A28%3A54.0242121Z'\"",
    "PartitionKey": "partitionKey",
    "RowKey": "rowKey",
    "Timestamp": "2023-02-09T22:28:54.0242121+00:00",
    "Address": "address",
    "Forename": "forename",
    "Mobile": "mobile",
    "Surname": "surname"
}

Neither is populating the ETag correctly - User has a value of ETag: {} and TableEntity has a valid string value of an ETag "W/\"datetime'2023-02-09T22%3A28%3A54.0242121Z'\"" BUT it is is a string with a property name of odata.etag NOT an object of type ETag named ETag as per the ITableEntity implementation.

Further to this...

when I do a delete operation and require the ETag ifMatch for validation the validation works using the odata.etag property value and seemingly not using the ETag property as implemented with ITableEntity.


Update - Delete Method

public async Task<bool> DeleteItemAsync(TableEntity item, bool forceDelete)
{
        var response = await tableClient.DeleteEntityAsync(item.PartitionKey, item.RowKey, forceDelete? ETag.All : item.ETag);
        if (response.Status == 200 || response.Status == 201 || response.Status == 204) { return true; }
        else { throw new Exception($"The response was {response.Status} - {response.ReasonPhrase}"); }
}

So in effect - the ITableEntity implements a property ETag that is not being set and does not support the ETag property for validation.

I am SO confused - what do I need to do to get the ITableEntity ETag property assigned using the Azure.Data.Table.GetEntityAsync<TableEntity>(PK, RK) method and used in the Azure.Data.Table.DeleteEntityAsync(PK, RK, ETag) validation?

haPartnerships
  • 335
  • 1
  • 2
  • 13
  • Can you edit your question and include the complete code please? Also include the code for your `User` type. – Gaurav Mantri Feb 10 '23 at 04:47
  • Did you get a chance to look into [ETag Properties and OData MetaData](https://github.com/Azure/azure-sdk-for-net/pull/16315/files/556f93f1ee937f6a1b15d42ffbbbd4a7b5234e26#diff-c2caa7732ea13a7c296b8f174116972557b410bebb80989646add2ddf81de72b) – Rajesh Mopati Feb 10 '23 at 08:22
  • @GauravMantri - Question updated with the code for setting the tableClient, getting the entity, the User object class and the delete method. – haPartnerships Feb 10 '23 at 08:34
  • I did just look at the link you provided @RajeshM and can see the extension method ToOdataAnnotatedDictionary strips the ETag property from teh TableClient Dictionary - but don't see why it would be doing this when that extension is not being called. ETag should be available? – haPartnerships Feb 10 '23 at 08:36
  • ToOdataAnnotatedDictionary is not a built-in method in the .NET Framework or from any standard libraries. And it is likely a custom extension method defined by a particular application or library. And it is used to convert an IDictionary object representing a table entity's properties to a dictionary with OData annotations. – Rajesh Mopati Feb 15 '23 at 07:41
  • @haPartnerships Is this issue resolved? if so post it here as an answer to help community members with the same type of issue. – Naveen Sharma Mar 07 '23 at 09:00

0 Answers0