Using custom property types in Azure Tables with ASP.NET 5 DNX Core

試著忘記壹切 提交于 2019-12-12 09:07:09

问题


Azure Table Storage does not support many property types (List<>, TimeSpan, etc).

There are solutions like Lucifure Stash and Lokad.Cloud, but they are not compiling for DNX Core 5.0.

Is there a way to add support for custom property types in Azure Tables with DNX Core?


回答1:


One solution is to use reflection to iterate through all the “custom” properties of the entity and serialize them to JSON strings.

We can override TableEntity’s ReadEntity and WriteEntity methods to hook de-/serialization:

using System;
using System.Linq;
using System.Reflection;
using System.Collections.Generic;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Table;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

public abstract class CustomEntity : TableEntity
{
    public override IDictionary<string, EntityProperty> WriteEntity (OperationContext operationContext)
    {
        var properties = base.WriteEntity(operationContext);

        // Iterating through the properties of the entity
        foreach (var property in GetType().GetProperties().Where(property =>
                // Excluding props explicitly marked to ignore serialization
                !property.GetCustomAttributes<IgnorePropertyAttribute>(true).Any() &&
                // Excluding already serialized props
                !properties.ContainsKey(property.Name) &&
                // Excluding internal TableEntity props
                typeof(TableEntity).GetProperties().All(p => p.Name != property.Name)))
        {
            var value = property.GetValue(this);
            if (value != null)
                // Serializing property to JSON
                properties.Add(property.Name, new EntityProperty(JsonConvert.SerializeObject(value)));
        }

        return properties;
    }

    public override void ReadEntity (IDictionary<string, EntityProperty> properties, OperationContext operationContext)
    {
        base.ReadEntity(properties, operationContext);

        // Iterating through the properties of the entity
        foreach (var property in GetType().GetProperties().Where(property =>
                // Excluding props explicitly marked to ignore serialization
                !property.GetCustomAttributes<IgnorePropertyAttribute>(true).Any() &&
                // Excluding props which were not originally serialized
                properties.ContainsKey(property.Name) &&
                // Excluding props with target type of string (they are natively supported)
                property.PropertyType != typeof(string) &&
                // Excluding non-string table fields (this will filter-out 
                // all the remaining natively supported props like byte, DateTime, etc)
                properties[property.Name].PropertyType == EdmType.String))
        {
            // Checking if property contains a valid JSON
            var jToken = TryParseJson(properties[property.Name].StringValue);
            if (jToken != null)
            {
                // Constructing method for deserialization 
                var toObjectMethod = jToken.GetType().GetMethod("ToObject", new[] { typeof(Type) });
                // Invoking the method with the target property type; eg, jToken.ToObject(CustomType)
                var value = toObjectMethod.Invoke(jToken, new object[] { property.PropertyType });

                property.SetValue(this, value);
            }
        }
    }

    private static JToken TryParseJson (string s)
    {
        try { return JToken.Parse(s); }
        catch (JsonReaderException) { return null; }
    }
}

Now, if we inherit our table entities from the CustomEntity class, we can freely use properties with any types supported by Json.NET.



来源:https://stackoverflow.com/questions/34557105/using-custom-property-types-in-azure-tables-with-asp-net-5-dnx-core

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!