Search code examples
c#azureazure-storage

The best way to insert odata type to json payload when use rest api insert data to azure table storage


When I use azure table storage Insert Entity api to insert data.

There are some types like dateTime,int in my entity class. And as per this doc: By default a property is created as type String, unless you specify a different type.

So I wonder which is the best way to add the odata type to the json payload? The generated json payload with odata type added should like below:

enter image description here

And my current solution is that after the json string is generated, I treat it as string, and add the odata type directly into the json. But I think there should be more better way for this.

My code like below:

Entity class:

public class MyClass
{

    public string PartitionKey { get; set; }
    public string RowKey { get; set; }
    public string Name { get; set; }

    public Guid TestId { get; set; }
}

The main method:

        static void Main(string[] args)
        {

            string url_with_sasToken = "https://xxx.table.core.windows.net/ttt?sasToken";

            MyClass entity = new MyClass
            {
                PartitionKey = "ivan2",
                RowKey = "y1",
                Name = "jack60",
                TestId = Guid.NewGuid()
            };

            //here, I add the odata type for Guid type
            string s = JsonConvert.SerializeObject(entity).Replace("}","");
            s += ",\"[email protected]\"" + ":" + "\"Edm.Guid\"}";
            Console.WriteLine(s);

            var content = new StringContent(s, Encoding.UTF8, "application/json");

            using (HttpClient client = new HttpClient())
            {
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new
          MediaTypeWithQualityHeaderValue("application/json"));
                var t2 = client.PostAsync(url_with_sasToken , content).GetAwaiter().GetResult();
                Console.WriteLine(t2.StatusCode);
            }

        }

Solution

  • IMHO, a better way to do this is to make use of Reflection and dynamically create JSON by iterating over public properties of a class. You can pick only those properties types of which are supported by Table service (e.g. Guid, DateTime etc.)

    That way you're not constantly changing the serialization code to reflect changes in your class definition. In any case using + sign for string concatenation is a bad idea :).

    For reference, you can take a look at the code for TableEntity class in Storage SDK. I downloaded the code for release 9.3.2 from Github (https://github.com/Azure/azure-storage-net/releases/tag/v9.3.2) as this was the last version that supported Table in the SDK.