1. 首页>
  2. 技术文章>
  3. .net core 使用Microsoft.Extensions.Caching.Redis序列化问题

.net core 使用Microsoft.Extensions.Caching.Redis序列化问题

8/1/18 11:19:34 PM 浏览 1862 评论 0

.net core redis 序列化 aspectcore

在.net core 中,使用Microsoft.Extensions.Caching.Redis可以很方便的集成Redis,这里涉及到字节数组转成对象和对象转成字节数组,而我们对此有两个基本要求:

1、要做到不需要在序列化的类上增加序列化标识;

2、要求对返回的对象可以不设定具体类型返回,只返回object,因我们在aop中需要用到这个object.

若使用的是AspectCore做AOP的话,那么拦截处理需要加缓存的事件,如下:

public class CacheAttribute : AbstractInterceptorAttribute
{
    [FromContainer]
    public ICacheService CacheService {
        get;
        set;
    }
    public async override Task Invoke(AspectContext context, AspectDelegate next)
    {
        var key = new Cachekey(context.ServiceMethod, context.Parameters).GetHashCode().ToString();
        var cacheValue = CacheService.Get(key);
        if (cacheValue != null)
        {
            context.ReturnValue = cacheValue;
        }
        else
        {
            await next(context);
            if (!string.IsNullOrWhiteSpace(key) && context.ReturnValue != null)
                CacheService.Add(key, context.ReturnValue);
        }
    }
}

key是根据方法和传参生成一个HashCode,你也可以用自己的方法去生成这个key,缓存获取的方法如下:

public object Get(string key)
{
    var rValue = _cache.Get(key);
    if (rValue != null)
    {
        var value = Json.ToObject(rValue);
        return value;
    }
    return null;
}

Json类代码如下:

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace MyCore.Infrastructure.Helpers
{
    public class Json
    {
        /// <summary>
        /// Json序列化器
        /// </summary>
        static readonly JsonSerializer JsonSerializer = new JsonSerializer();
        #region ToObject<T>(将Json字符串转换为对象)
        /// <summary>
        /// 将Json字符串转换为对象
        /// </summary>
        /// <param name="json">Json字符串</param>
        public static T ToObject<T>(string json)
        {
            if (string.IsNullOrWhiteSpace(json))
                return default(T);
            return JsonConvert.DeserializeObject<T>(json);
        }
        #endregion
        #region ObjectToByte(将对象转换成字节数组)
        public static byte[] ObjectToByte(object obj)
        {
            var typeName = Reflection.GetTypeName(obj.GetType());
            using (var ms = new MemoryStream())
            {
                using (var tw = new StreamWriter(ms))
                {
                    using (var jw = new JsonTextWriter(tw))
                    {
                        jw.WriteStartArray();// [
                        jw.WriteValue(typeName);// "type"
                        JsonSerializer.Serialize(jw, obj);// obj
                        jw.WriteEndArray();// ]
                        jw.Flush();
                        return ms.ToArray();
                    }
                }
            }
        }
        #endregion
        #region ToObject(字节数组转成对象)
        /// <summary>
        /// 反序列化对象
        /// </summary>
        /// <param name="value">值</param>
        /// <returns></returns>
        public static object ToObject(byte[] value)
        {
            using (var ms = new MemoryStream(value, writable: false))
            {
                using (var tr = new StreamReader(ms))
                {
                    using (var jr = new JsonTextReader(tr))
                    {
                        jr.Read();
                        if (jr.TokenType == JsonToken.StartArray)
                        {
                            // 读取类型
                            var typeName = jr.ReadAsString();
                            var type = Type.GetType(typeName, throwOnError: true);// 获取类型
                            // 读取对象
                            jr.Read();
                            return JsonSerializer.Deserialize(jr, type);
                        }
                        else
                        {
                            throw new InvalidDataException("JsonTranscoder 仅支持 [\"TypeName\", object]");
                        }
                    }
                }
            }
        }
        #endregion
        #region ToJson(将对象转换为Json字符串)
        /// <summary>
        /// 将对象转换为Json字符串
        /// </summary>
        /// <param name="target">目标对象</param>
        /// <param name="isConvertToSingleQuotes">是否将双引号转成单引号</param>
        public static string ToJson(object target, bool isConvertToSingleQuotes = false)
        {
            if (target == null)
                return "{}";
            var result = JsonConvert.SerializeObject(target);
            if (isConvertToSingleQuotes)
                result = result.Replace("\"", "'");
            return result;
        }
        #endregion
    }
}


网友讨论