在ASP.NET 5 DNX Core中使用Azure表中的自定义属性类型 [英] Using custom property types in Azure Tables with ASP.NET 5 DNX Core
问题描述
Azure表存储不支持许多属性类型(列表<>,时间跨度等).
Azure Table Storage does not support many property types (List<>, TimeSpan, etc).
有诸如Lucifure Stash和Lokad.Cloud之类的解决方案,但它们并未针对DNX Core 5.0进行编译.
There are solutions like Lucifure Stash and Lokad.Cloud, but they are not compiling for DNX Core 5.0.
是否可以使用DNX Core在Azure表中添加对自定义属性类型的支持?
Is there a way to add support for custom property types in Azure Tables with DNX Core?
推荐答案
一种解决方案是使用反射来遍历实体的所有自定义"属性,并将其序列化为JSON字符串.
One solution is to use reflection to iterate through all the "custom" properties of the entity and serialize them to JSON strings.
我们可以重写TableEntity的ReadEntity
和WriteEntity
方法来挂钩反序列化:
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; }
}
}
现在,如果我们从CustomEntity
类继承表实体,则可以自由使用Json.NET支持的任何类型的属性.
Now, if we inherit our table entities from the CustomEntity
class, we can freely use properties with any types supported by Json.NET.
这篇关于在ASP.NET 5 DNX Core中使用Azure表中的自定义属性类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!