当前位置:  开发笔记 > 编程语言 > 正文

在Azure表中使用ASP.NET 5 DNX Core的自定义属性类型

如何解决《在Azure表中使用ASP.NET5DNXCore的自定义属性类型》经验,为你挑选了1个好方法。

Azure表存储不支持许多属性类型(List <>,TimeSpan等).

有一些解决方案,如Lucifure Stash和Lokad.Cloud,但他们没有为DNX Core 5.0编译.

有没有办法在使用DNX Core的Azure表中添加对自定义属性类型的支持?



1> Elringus..:

一种解决方案是使用反射来遍历实体的所有"自定义"属性,并将它们序列化为JSON字符串.

我们可以覆盖TableEntity ReadEntityWriteEntity方法来挂钩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 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(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 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(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; }
    }
}

现在,如果我们从CustomEntity类继承我们的表实体,我们可以自由地使用Json.NET支持的任何类型的属性.

推荐阅读
sx-March23
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有