面向云技术架构 - 痴者工良

  • 首页
  • 工良写的电子书
    • kubernetes 教程
    • 从 C# 入门 Kafka
    • 多线程和异步
    • 动态编程-反射、特性、AOP
    • 表达式树
  • 本站文章导航
  • 隐私政策
愿有人陪你颠沛流离
遇到能让你付出的事物或者人,都是一种运气。
能遇到,就该珍惜。或许你们最终没能在一起,但你会切实地感受到力量。
正因为这样,那段相遇才变得有价值,才没有辜负这世间的每一段相遇。
  1. 首页
  2. .NET
  3. 正文

ASP.NET Core Post Json 请求参数模型类型转换

2021年7月12日 1410点热度 0人点赞 1条评论
内容纲要

在后端中,当有分布式需求时,我们常常使用 64位 的数字类型表示字段类型,但是前端并不支持超过 16 位长度的数值类型,所以后端长度较大的 long、ulong 数值传到后端,其准确度就已经丢失。

解决方法就是将 ulong、long 转为字符串,传递给后端。

    public class TentantQueryDto
    {
        public ulong Id { get; set; }
    }

这是一个后端模型, Id 为 64 位数值,我们要做到前端传递 string,自动转 ulong;后端传递 ulong,自动返回 string 给前端。

首先定义两个转换器:

    public class ULongToStringConverter : JsonConverter<ulong>
    {
        public override ulong Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            string stringValue = reader.GetString();
            if (string.IsNullOrWhiteSpace(stringValue)) return 0;

            if (ulong.TryParse(stringValue, out var value)) return value;
            return 0;
        }

        public override void Write(Utf8JsonWriter writer, ulong value, JsonSerializerOptions options)
        {
            writer.WriteStringValue(value.ToString());
        }
    }
    public class StringToULongConverter : JsonConverter<string>
    {
        public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            return reader.GetString();
        }

        public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
        {
            ulong result = 0;
            if (string.IsNullOrWhiteSpace(value)) result = 0;
            if (ulong.TryParse(value, out var number)) result = number;

            writer.WriteNumberValue(result);
        }
    }

这两个转换器没有什么特别的地方,只是将数值和string互转。

然后定义特性,这个特性告诉我们应该使用什么字段、怎么在前后端传递 Json 时,自动转换参数类型:

    /// <summary>
    /// string 和 ulong 转换器
    /// </summary>
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Property, AllowMultiple = false)]
    public class ULongConverterAttribute : JsonConverterAttribute
    {
        public override JsonConverter CreateConverter(Type typeToConvert)
        {
            if (typeToConvert == typeof(ulong))
                return new ULongToStringConverter();
            if (typeToConvert == typeof(string))
                return new StringToULongConverter();

            return base.CreateConverter(typeToConvert);
        }
    }

在要被转换的字段上使用该特性:

    public class TentantQueryDto
    {
        [ULongConverter]
        public ulong Id { get; set; }
    }

这样,我们无需另外加上转换代码,在前后端传递数据时, ASP.NET Core 调用转换器自动转换。

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可
标签: asp core json net post
最后更新:2021年7月12日

痴者工良

高级程序员劝退师

点赞
< 上一篇
下一篇 >

文章评论

  • 痴者工良

    using System.Reflection;
    using System.Text.Json.Serialization;
    
    namespace System.Text.Json;
    
    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
    public class LongStringConverterAttribute : JsonConverterAttribute
    { 
        public override JsonConverter CreateConverter(Type typeToConvert)
        {
            if (typeToConvert == typeof(long))
                return new LongToStringConverter();
            if (typeToConvert == typeof(ulong))
                return new UlongToStringConverter();
    
            return base.CreateConverter(typeToConvert);
        }
    }
    
    public class LongToStringConverter : JsonConverter
    {
        public override bool CanConvert(Type typeToConvert)
        {
            return typeToConvert == typeof(long);
        }
    
        public override long Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            string? stringValue = reader.GetString();
            if (string.IsNullOrWhiteSpace(stringValue)) return 0;
    
            if (long.TryParse(stringValue, out var value)) return value;
            return 0;
        }
    
        public override void Write(Utf8JsonWriter writer, long value, JsonSerializerOptions options)
        {
            writer.WriteStringValue(value.ToString());
        }
    }
    
    public class UlongToStringConverter : JsonConverter
    {
        public override bool CanConvert(Type typeToConvert)
        {
            return typeToConvert == typeof(ulong);
        }
    
        public override ulong Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            string? stringValue = reader.GetString();
            if (string.IsNullOrWhiteSpace(stringValue)) return 0;
    
            if (ulong.TryParse(stringValue, out var value)) return value;
            return 0;
        }
    
        public override void Write(Utf8JsonWriter writer, ulong value, JsonSerializerOptions options)
        {
            writer.WriteStringValue(value.ToString());
        }
    }
    

    2022年7月22日
    回复
  • razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
    取消回复

    COPYRIGHT © 2022 whuanle.cn. ALL RIGHTS RESERVED.

    Theme Kratos Made By Seaton Jiang

    粤ICP备18051778号

    粤公网安备 44030902003257号