Git Product home page Git Product logo

swifter.json's Introduction

Swifter.Json

A powerful, easy-to-use and fastest json serializer and deserializer on .Net platforms.

If you want to use Swifter.Json, please download or install the latest version on Nuget.

如果您想使用 Swifter.Json,请在 Nuget 上下载或安装最新版本。

1.6.0 Release Notes

  1. Fix known bugs.
  2. Remove dependency: Swiffer.Underlying.
  3. Remove sensitive structures: MethodTable and FieldDesc. (Fast reflection for static fields is no longer supported, but has no effect on json.)
  4. Supports serialization and deserialization of very large files.

Easy to use 简单使用

public class Demo
{
    public int Id { get; set; }
    public int Name { get; set; }
    public static void Main()
    {
        var json = JsonFormatter.SerializeObject(new { Id = 123, Name = "Dogwei" });
        var dic = JsonFormatter.DeserializeObject<Dictionary<string, object>>(json);
        var obj = JsonFormatter.DeserializeObject<Demo>(json);
    }
}

Supported data structures and types 支持的数据类型和结构

bool, byte, sbyte, short, ushort, char, int, uint, long, ulong, IntPtr, UIntPtr,
float, double, decimal, string, enum, DateTime, DateTimeOffset, TimeSpan, Guid,
BigInteger, Complex, DBNull, Nullable<T>, Tuple<...>, ValueTuple<...>, Version,
Uri, Assembly, Type, MemberInfo, MethodInfo, FieldInfo, PropertyInfo, ConstructorInfo,	
EventInfo, Array, Multidimensional-Arrays, IList, IList<T>, ICollection, ICollection<T>,	
IDictionary, IDictionary<TKey, TValue>, IEnumerable, IEnumerable<T>, DataSet, DataTable,	
DataRow, DbRowObject, DbDataReader...	
Other types are treated as object 其他类型当作对象处理	

Supported platforms and runtimes 支持的平台和运行时

.NET Framework 2.0+, .NET Core 2.0+, .NET Standard 2.0+, MONO, MONO AOT, MONO FULL-AOT,
Unity, Xamarin.iOS, Xamarin.Android

Uncertain:Unity IL2CPP

Unsupported: Sliverlight

Note:
    .NET Core use the Core version, and other platforms use the Framework version or Standard version.
    Because the Core version is performance-optimized.
    the Framework version and Standard version are optimized for compatibility.
    the Framework version and Standard version can run directly on AOT platforms.
注意:
    .NET Core 请使用 Core 版本,其他平台和运行时请使用 Framework 版本或 Standard 版本。
    因为 Core 版本专为性能优化,Framework 版本和 Standard 版本为兼容性优化。
    Framework 版本和 Standard 版本可以直接在 AOT 平台上运行。

Supported features 支持的功能

LoopReferencingNull:
    Objects that appear a loop reference during serialization are treated as Null.
    在序列化时出现循环引用的对象将用 Null 表示。
    
MultiReferencingReference:
    Allow use { "$ref": "#/obj/1/target" } to represent objects that are repeatedly referenced.
    允许使用 { "$ref": "#/obj/1/target" } 写法表示重复引用的对象。
    
AsOrderedObjectDeserialize
    Perform as-ordered object fields parsing, which can improve parsing performance of ordered Json objects.
    执行假定有序的对象字段解析,这可以提高有序 Json 对象的解析性能。
    
DeflateDeserialize
    Perform deflate(no spaces) Json parsing, which can improve parsing performance.
    执行紧凑(无空白字符)的 Json 解析,这可以提高解析性能。
    
Indented
    Json indents and wraps during serialization, which makes Json beautiful.
    序列化时对 Json 进行缩进和换行,让 Json 变得好看。
    
CamelCaseWhenSerialize
    Convert the fields name in the object to camel case during serialization. 
    序列化时,将对象中的字段名称转换为骆驼命名法。 ::: new { Name = "Dogwei" } -> { "name": "Dogwei" }
    
IgnoreNull | IgnoreZero | IgnoreEmptyString
    Null, 0, "" values are ignored during serialization. 
    序列化时分别跳过 Null, 0 和 "" 值。 ::: { A = (string)null, B = 0, C = "", D = 1 } -> { "D": 1 }
    
For more features, please see Swifter.Json.JsonFormatterOptions enum.
更多功能请看 Swifter.Json.JsonFormatterOptions 配置项。

Performance 性能

Performance

ServiceStack.Json, Jil, LitJson, NetJson and etc libraries are not shown because there are too many errors; if necessary, you can clone the test program on GitHub and run. Most of the Json serialization libraries of .NET have been included.

Demos 示例

(1) Deserialize to dynamic 反序列化为 dynamic
        var list = new List<object>
        {
            { new Dictionary<string, object>() { { "Id", 1 }, { "Name", "Dogwei" } }},
            { new Dictionary<string, object>() { { "Id", 2 }, { "Name", "sg" } }},
            { new Dictionary<string, object>() { { "Id", 3 }, { "Name", "cxw" } }},
            { new Dictionary<string, object>() { { "Id", 4 }, { "Name", "eway" } }},
            {
                new Dictionary<string, object>() { 
                    { "Id", 5 }, 
                    { "Name", "Xinwei Chen" }, 
                    { "Data", new Dictionary<string, object> { { "Age", 21 }, { "Sex", "Male" } } }
                }
            },
        };

        var json = JsonFormatter.SerializeObject(list);

        dynamic dym = JsonFormatter.DeserializeObject<JsonValue>(json);

        Console.WriteLine(dym[0].Name); // Dogwei
        Console.WriteLine(dym[1].Name); // sg
        Console.WriteLine(dym[2].Id); // 3
        Console.WriteLine(dym[3].Id); // 4
        Console.WriteLine(dym[4].Data.Age); // 21
(2) Attributes 特性
[RWObject(SkipDefaultValue = RWBoolean.Yes)]
public class Demo
{
    public int Id;
    public string Name;
    [RWField("Age")]
    private int age;
    [RWField(SkipDefaultValue = RWBoolean.No)]
    public int? Sex;
    [RWFormat("yyyy-MM-dd")]
    public DateTime Birthday { get; set; }

    public static void Main()
    {
        var obj = new Demo { Name = "Dogwei", age = 24, Birthday = DateTime.Parse("1996-01-08") };
        var json = JsonFormatter.SerializeObject(obj);
        var dest = JsonFormatter.DeserializeObject<Demo>(json);

        Console.WriteLine(json);
        // {"Age":24,"Birthday":"1996-01-08","Name":"Dogwei","Sex":null}
    }
}
(3) Advanced 进阶用法
    var datatable = ValueCopyer.ValueOf(new[] {
        new { Id = 1, Guid = Guid.NewGuid(), Name = "Dogwei" },
        new { Id = 2, Guid = Guid.NewGuid(), Name = "cxw" },
        new { Id = 3, Guid = Guid.NewGuid(), Name = "sg" },
        new { Id = 4, Guid = Guid.NewGuid(), Name = "eway" },
    }).ReadDataTable();
    
    var jsonFormatter = new JsonFormatter(JsonFormatterOptions.Indented);
    jsonFormatter.SetDataTableRWOptions(DataTableRWOptions.WriteToArrayFromBeginningSecondRows);
    jsonFormatter.SetValueFormat<Guid>("N");

    var json = jsonFormatter.Serialize(datatable);
    var dest = JsonFormatter.DeserializeObject<DataTable>(json);

    Console.WriteLine(json);
    /*
    [
      {
        "Guid": "1615527f673c499fac8de16847ad8783",
        "Id": 1,
        "Name": "Dogwei"
      },
      [
        "a23d1980185749118796fb5db7fb57a1",
        2,
        "cxw"
      ],
      [
        "9f76a802148d420da52716cf8a90b13d",
        3,
        "sg"
      ],
      [
        "ba03739cd44a49fab7b3de2558f84ebe",
        4,
        "eway"
      ]
    ]
    */
    var dic = new Dictionary<string, object>
    {
        { "Id", 123 },
        { "SystemNo", "9110" },
        { "IMEI", 31415926535897UL }
    };
    
    var jsonFormatter = new JsonFormatter();
    jsonFormatter.SetValueInterface(new MyUInt64Interface());

    var json = jsonFormatter.Serialize(dic);
    var obj = new { Id = 0, SystemNo = "", IMEI = 0UL, SIMId = 999 };

    jsonFormatter.DeserializeTo(json, RWHelper.CreateWriter(obj));

    Console.WriteLine(json); // {"Id":123,"SystemNo":"9110","IMEI":"0x1C92972436D9"}

    Console.WriteLine(obj.Id); // 123
    Console.WriteLine(obj.IMEI); // 31415926535897
    Console.WriteLine(obj.SIMId); // 999

    public class MyUInt64Interface : IValueInterface<ulong>
    {
        public unsafe ulong ReadValue(IValueReader valueReader)
        {
            var str = valueReader.ReadString();

            fixed (char* chars = str)
            {
                return NumberHelper.GetNumberInfo(chars, str.Length).ToUInt64(16);
            }
        }

        public void WriteValue(IValueWriter valueWriter, ulong value)
        {
            valueWriter.WriteString($"0x{value:X}");
        }
    }
(4) Use Swifter.Json on AspNetCore. 在 AspNetCore 上使用 Swifter.Json
First, reference the latest version of Swifter.Extensions.AspNetCore package on Nuget. And configure as follows.
首先在 Nuget 上引用最新的 Swifter.Extensions.AspNetCore 包,并如下配置。

    /** Configure */
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.ConfigureJsonFormatter();
        }
    }
    
In this way, when the client use the application/json header request,
it will use Swifter.Json serialize results and deserialize parameters.
Or you can use the JsonResult to explicitly return Json content.
这样配置后,当客户端使用 application/json 头请求时,就会使用 Swifter.Json 序列化返回值或反序列化参数。
或者您可以使用 JsonResult 显式的返回 Json 内容。

swifter.json's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

swifter.json's Issues

大佬,求使用 忽略对象内对象 教程

问个问题 json.net 忽略部分属性 问题 格式如下
假设不设置忽略属性,直接序列化后
{Name:'abc',age:12,student:{name:'abca',age:'sss'}}
但目前需要序列化时忽略部分属性,序列化后如下 student 有可能是数组类型
{Name:'abc',student:{age:'sss'}}
忽略属性是动态的,但父级和子级有可能属性名是一样的,有办法去除么?
忽略属性 可以做到 ["age","student.name"]

Support Type Declaration in JSON?

In Newtonsoft.Json, we can define the data type of the $data field through the $type pseudo-field to avoid data type ambiguity in RPC. Does Swifter.Json support the above features?

在Newtonsoft.Json中,我们可以通过 $type 伪字段来定义 $data 字段的数据类型,避免RPC时数据类型歧义。请问Swifter.Json支持上述功能吗?

枚举序列化

请问如何在序列化/反序列化的时候使用枚举值而不是flag?flag只是一堆数字,不利用阅读

序列化 float 数据小数位会失真?

把float数据序列化后小数位失真,而double又不会失真,而我从数据库取回的数据double会失真,float又不会失真,这就很尴尬了。

JsonFormatter.SerializeObject(12.1f)
"12.10000038146972"
JsonFormatter.SerializeObject(12.1d)
"12.1"

Unity2019.3.1 导入dll报错

下面时错误信息
C:\Program Files\Unity\Hub\Editor\2019.3.1f1\Editor\Data\Resources\PackageManager\BuiltInPackages\com.unity.ugui\Runtime\UI\Core\Layout\LayoutUtility.cs(134,74): error CS0433: The type 'Func<T1, TResult>' exists in both 'Swifter.Core, Version=1.5.0.3, Culture=neutral, PublicKeyToken=5c52005388a7b388' and 'netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'

求解决办法

关于在 Controller 上使用 [Produces("application/json")] 特性的问题

  • 测试环境:Asp.Net Core 3.0 Preview 8
  • 插件版本:Swifter.Extensions.AspNetCore v1.2.9.2

今天意外发现了一个问题,我不知道这种行为是否正常,还是 BUG。比如,下面的问题代码:

    [Produces("application/json")]
    [ApiController]
    [Route("api/[controller]")]
    public class TestController : ControllerBase
    {
        [HttpGet]
        public ActionResult<string> Get([FromQuery, BindRequired] string name)
        {
            return Ok(name);
        }
    }

这时候,访问 http://localhost:5000/api/Test?name=Test 就会报以下错误:

An unhandled exception occurred while processing the request.
ArgumentNullException: Value cannot be null. (Parameter 'encoding')
Microsoft.AspNetCore.Mvc.Infrastructure.MemoryPoolHttpResponseStreamWriterFactory.CreateWriter(Stream stream, Encoding encoding)

但是,这种行为在 Asp.Net Core 3.0 Preview 8 默认生成的模板程序中会正常返回一个字符串。

临时解决办法是 return new JsonResult(name);

序列化double,float这些小数格式化有问题,位数和数值不对

       DateTime? time2 = null;
        Hashtable hs = new Hashtable();
        hs["name"] = "xiaocui";
        hs["time"] = DateTime.Now;
        hs["time2"] = time2;
        hs["count"] = int.MaxValue;
        hs["money"] = decimal.MinValue;
        hs["double_test"] = 3.1415;
        hs["float_test"] = 3.1415;
        var json = JsonFormatter.SerializeObject(hs);

        Response.Clear();
        Response.Write(json);

.net4.5输出结果
{"money":-79228162514264337593543950335,"count":2147483647,"float_test":3.1415000000000002,"time2":null,"time":"2019-09-21T22:35:03.870+08:00","name":"xiaocui","double_test":3.1415000000000002}

我的值3.1415 变成了3.1415000000000002

JsonFormatterOptions.MultiReferencingNull breaks multi-dimensional arrays

When the JsonFormatterOptions.MultiReferencingNull option is enabled the output of each dimension in a multi-dimensional array is always null.

The LINQPad statements below demonstrate the problem.

var foo = new[,] { { 1, 2, 3 }, { 4, 5, 6 } };

JsonFormatter.SerializeObject(foo)
    .Dump("Without MultiReferencingNull");

JsonFormatter.SerializeObject(foo, JsonFormatterOptions.MultiReferencingNull)
    .Dump("With MultiReferencingNull");

Without MultiReferencingNull: [[1,2,3],[4,5,6]]

With MultiReferencingNull: [null,null]

I discovered this issue when upgrading from 1.1.2 to 1.2.9.5.

反序列化含无set方法的属性的类时出现异常

dotnet sdk版本:2.2.105
反序列化含无set方法的属性时出错
例如:
命名空间System.Net下的Cookie类的某个实例经Swifter.JSON序列化后形成如下的json

{
            "Comment": "",
            "CommentUri": null,
            "Discard": false,
            "Domain": ".bilibili.com",
            "Expired": false,
            "Expires": "2019-05-19T09:51:39.000+08:00",
            "HttpOnly": false,
            "Name": "bili_jct",
            "Path": "/",
            "Port": "",
            "Secure": false,
            "TimeStamp": "2019-04-19T09:51:41.313+08:00",
            "Value": "some_value",
            "Version": 0
}

浏览sdk定义可发现其中TimeStamp属性无set访问器。
image

在反序列化这个json为Cookie类的实例时出现异常。
image

unity的il2cpp模式下无法使用

暂时无法提供有效的调试信息,后面会继续测试

根据以前调试Json.Net的经验,可能是AOT编译的问题,具体可以参考

Newtonsoft.Json-for-Unity
Unity文档

IL2CPP模式调试实在是不方便,暂时还没有获得有用的信息,以上只是推测

如果需要,我可以提供测试用的工程文件

关于使用 [FromBody] string content 中反序列化的内容为类型信息的问题

如题,在 [FromBody] string content 这样的使用场景中,content 字段的内容为它的类型信息。

  • 测试环境:ASP.NET Core 3.0 Preview 8
  • Package:Swifter.Extensions.AspNetCore v1.2.9.5

问题代码如下所示:

    public class RawJsonInputFormatter : InputFormatter
    {
        public RawJsonInputFormatter()
        {
            this.SupportedMediaTypes.Add("application/json");
        }

        public override async Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context)
        {
            using(var reader = new StreamReader(context.HttpContext.Request.Body))
            {
                var content = await reader.ReadToEndAsync();
                return await InputFormatterResult.SuccessAsync(content);
            }
        }

        protected override bool CanReadType(Type type)
        {
            return type == typeof(string);
        }
    }

然后在 Startup.cs 中添加如下代码:

           services.AddControllers(options =>
            {
                options.InputFormatters.Insert(0, new RawJsonInputFormatter());
            });

然后随便构造一个 Controller,使用 [FromBody]string content 这样的参数,即可重现问题。

您好,想问下替代json.net方面的设置,enum和CamelCase。

版本:Swifter.Json 1.4.0

目前设置如下
1:处理时间格式
ValueInterface.SetValueFormat("yyyy-MM-dd HH:mm:ss");
2:处理long类型主键序列化成string
ValueInterface.SetInterface(new LongIdInterface());

预期目标:
1:支持enum,序列化成int,启用JsonFormatterOptions.OnFilter后,可以实现,但是对不存在的字段反序列化会报错。
2:CamelCase需要自己实现么?

json字符串中存在注释时,注释如果在某些特殊位置,反序列化会报异常

        string str = "{\r\n    \"Test\": \"Json Config Parser\",\r\n\r\n    \"User\": {\r\n        \"Name\": \"Wangxm\",\r\n        \"Age\": 18 //放这里没事\r\n    },\r\n\r\n    \"Country\": [\"China\", \"USA\", \"Russia\"]\r\n}\r\n";
        string str2 = "{\r\n    \"Test\": \"Json Config Parser\",\r\n\r\n    \"User\": {\r\n        \"Name\": \"Wangxm\",\r\n        \"Age\": 18\r\n    },\r\n\r\n    \"Country\": [\"China\", \"USA\", \"Russia\"]//这里会出错\r\n}\r\n";

        dynamic jsonObj = JsonFormatter.DeserializeObject<dynamic>(str);    //正常
        dynamic jsonObj2 = JsonFormatter.DeserializeObject<dynamic>(str2);    //报错

Swifter 反序列话,Json串比实体字段多,出现异常

目前我的情况出现,我存储的Json 串 比对应实体字段多,会出现这种情况,怎么解决呢?这种情况就不能在实体里面设置对应的属性了。 比如我有个json 串 {"Test":"1",Id:1},但是我的实体只有Id 字段。

image

SwifterJson Crashes in SerializerTests on .NET 5

SerializerTests.exe -test combined -N 100000,200000,500000,1000000 -serializer swifter

SwifterJson crashes during the "normal test" with

Json deserialize failed.:   Json deserialize failed.: 1 exception
        Catch: instance void [Swifter.Json] Swifter.Json.JsonFormatter +< DeserializeObjectAsync > d__134`1[System.__Canon]::MoveNext()
            Swifter.Json.JsonDeserializer`1[Swifter.Json.JsonDeserializeModes + Verified].FastReadObject(class Swifter.RW.IDataWriter`1<value class Swifter.Tools.Ps`1<wchar>>)
   FastObjectRWCreater_Book_d1913bb0372f40a5a3ca8ae5210d4a51.ReadValue(class Swifter.RW.IValueReader)
   Swifter.RW.ListRW`2[System.__Canon, System.__Canon].OnWriteValue(int32,class Swifter.RW.IValueReader)
   Swifter.Json.JsonDeserializer`1[Swifter.Json.JsonDeserializeModes+Verified].SlowReadArray(class Swifter.RW.IDataWriter`1<int32>)
   Swifter.Json.JsonDeserializer`1[Swifter.Json.JsonDeserializeModes+Verified].ReadArray(class Swifter.RW.IDataWriter`1<int32>)
   Swifter.RW.ListInterface`2[System.__Canon, System.__Canon].ReadValue(class Swifter.RW.IValueReader)
   FastObjectRW_BookShelf_b2eb1b0060b9498db34ca3b37cfb0ec2.OnWriteValue(value class Swifter.Tools.Ps`1<wchar>,class Swifter.RW.IValueReader)
   Swifter.Json.JsonDeserializer`1[Swifter.Json.JsonDeserializeModes+Verified].FastReadObject(class Swifter.RW.IDataWriter`1<value class Swifter.Tools.Ps`1<wchar>>)
   FastObjectRWCreater_BookShelf_ac8592457cd04421981eeb0a06342bf0.ReadValue(class Swifter.RW.IValueReader)
   Swifter.Json.JsonFormatter.DeserializeObject(wchar*, int32)
   Swifter.Json.JsonFormatter.DeserializeObject(class System.String)
   Swifter.Json.JsonFormatter+<DeserializeObjectAsync>d__134`1[System.__Canon].MoveNext()
   System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start(!!0&)
   System.Runtime.CompilerServices.AsyncValueTaskMethodBuilder`1[System.__Canon].Start(!!0&)
   Swifter.Json.JsonFormatter.DeserializeObjectAsync(class System.IO.Stream,class System.Text.Encoding)
   SerializerTests.Serializers.SwifterJson`1[System.__Canon].Deserialize(class System.IO.Stream)
   SerializerTests.TestBase`2[System.__Canon, System.__Canon].TestDeserializeOnlyAndTouch(class System.IO.MemoryStream,int32,!0&)
   SerializerTests.TestBase`2+<>c__DisplayClass39_0[System.__Canon, System.__Canon].<TestDeserialize>b__0()
   SerializerTests.TestBase`2[System.__Canon, System.__Canon].Test(int32,class System.Action,bool)
   SerializerTests.TestBase`2[System.__Canon, System.__Canon].TestDeserialize(int32, int32)
   SerializerTests.Test_O_N_Behavior.TestCombined(int32[], int32)
   SerializerTests.Program.Combined()
   SerializerTests.Program.Run()
   SerializerTests.Program.Main(class System.String[])

Is this expected? For now I need to uncomment it because it does not make the test suite pass.

请教一个问题

var task = JsonSerializer.NonGeneric.Utf8.SerializeAsync(Data, stream).AsTask();
用我们的框架怎么替换。

protobuf生成的类无法序列化,自己实现自定义映射处理也无法正常工作

因为google protobuf的数组转换成c#类是RepeatedField 。
RepeatedField只有 get; 是个只读属性
我无法正常的序列化他
所以我想自己实现一个IValueInterface
但是遇到了以下问题
请问IValueInterface 是不是不支持多重嵌套?

  public class valueMaper<T> : IValueInterface<RepeatedField<T>>
    {
        public RepeatedField<T> ReadValue(IValueReader valueReader)
        {
            Console.WriteLine("这个无法触发");

            return null;
        }

        public void WriteValue(IValueWriter valueWriter, RepeatedField<T> value)
        {
            valueWriter.WriteString("这个可以触发");
        }
    }

建议实现 Newtonsoft.Json 的JsonConverter来实现 设置字段的序列化格式

您的现有的这种方式 通过InterfaceType 或者[RWFormat("yyyy-MM-dd HH:mm:ss")] 感觉用起来不太方便,尤其是第二种 我这个实体有可能是多个接口使用A接口反 "yyyy-MM-dd" ,B接口返回“yyyy-MM-dd HH:mm:ss” 格式,
第一种也是 假如我是long类型 在转json的时候需要转为string类型, 必须要先定义一个类型
public class LongId
{
public long Value { get; set; }
}
很奇怪,当然我不知道是不是我的用法有问题

使用JsonFormatter.SerializeObject和jsonFormatter.Serialize结果不一致

使用JsonFormatter.SerializeObject和jsonFormatter.Serialize序列化通一个object结果不一致
SerializeObject可以正确序列化,Serialize会抛出异常
对象类型只有string和boo类型和DateTime?和DateTime类型
Snipaste_2020-02-18_12-41-44

在 Swifter.Json.JsonSerializer1.CheckObjectReference(IDataReader dataReader) 在 Swifter.Json.JsonSerializer1.WriteObject(IDataReader1 dataReader) 在 FastObjectRW_LicenseInfo_bce3720ae30443e28ef3cb6d78658fb0_Creater.WriteValue(IValueWriter , LicenseInfo ) 在 Swifter.RW.ValueInterface1.Write(IValueWriter valueWriter, Object value)
在 Swifter.RW.ObjectInterface.WriteValue(IValueWriter valueWriter, Object value)
在 Swifter.RW.ValueInterface1.WriteValue(IValueWriter valueWriter, T value) 在 Swifter.Json.JsonFormatter.Serialize[T,TMode](T value, HGlobalCache1 hGCache, JsonFormatterOptions options)
在 Swifter.Json.JsonFormatter.Serialize[T](T value, HGlobalCache`1 hGCache)
在 Swifter.Json.JsonFormatter.Serialize[T](T value)

关于字典和枚举

如果字典的Key是枚举类型,序列化的时候会被忽略;如果字典的Value是枚举类型,可以序列化,但是,枚举没有以索引保存而是转成了字符串,这样无法被反序列化。不知道是不是我用法有问题,请问有没有什么设置可以解决或者考虑在新版本添加下支持,多谢。

忽略属性放到MetaData里不起作用

有时候实体类是生成的,想把特性单独放到一个MetaData类中,把RWField特性放到MetaData类中好像不起作用。类似的.Net Core 中的 DataAnnotations 中的特性这样作都是可以的。代码如下,ApirolesMetaData类实际只起到一个特性的作用,但可以随便修改,而Apiroles是生成的,一般不手动修改,因为一修改再生成就变回去了。
.Net DataAnnotations示例: 外部链接

public class ApirolesMetaData
{
   [RWField(Access = RWFieldAccess.Ignore)]
   public string Name { get; set; }
}


[ModelMetadataType(typeof(ApirolesMetaData))]
public partial class Apiroles
{
   public string Name { get; set; }
}

设置jsonFormatter实例的ValueInterface不生效

在基于net4.6.1的项目使用时
使用ValueInterface.SetInterface(new DateInterface());全局设置有效,单独设置不生效
`
static void SwiferJsonTest()
{
var model = new TestDemo();
model.Id = 1;
model.LongId = 123213213212;
model.InsertTime = DateTime.Now;

        // 只要类型是 LongId 的值都会走 LongIdInterface。
        // ValueInterface<long>.SetInterface(new LongIdInterface());
        // ValueInterface<DateTime>.SetInterface(new DateInterface());

        var json = JsonFormatter.SerializeObject(model);
        Console.WriteLine(json);

        Console.WriteLine("************************");
        var jsonFormatter = new JsonFormatter();
        // 此方式只会对 jsonFormatter 这个实例生效。
        jsonFormatter.SetValueInterface(new DateInterface());
        var json2 = jsonFormatter.Serialize(model);
       
        Console.WriteLine(json2);


    }
    public class TestDemo
    {
        public int Id { get; set; }
        public long LongId { get; set; }
        public DateTime InsertTime { get; set; }
    }

    public class DateInterface : IValueInterface<DateTime>
    {
        public DateTime ReadValue(IValueReader valueReader)
        {
            return DateTime.Parse(valueReader.ReadString());
        }

        public void WriteValue(IValueWriter valueWriter, DateTime value)
        {
            valueWriter.WriteString(value.ToString("yyyy-MM-dd"));
        }
    }

`

序列化处理的Json的时间格式还是原始格式 不是yyyy-MM-dd ,设置全局的情况下 是序列化处理的格式是正常的

设置CannotSetException不生效

FastObjectRW.DefaultOptions &= ~FastObjectRWOptions.CannotSetException;

var obj1 = new ApiResult();
var obj2 = JsonFormatter.DeserializeObject(JsonFormatter.SerializeObject(obj1), typeof(ApiResult));
public class ApiResult
{
    [RWField(Name = "timestamp", Order = 99)]
    [RWObject(CannotSetException = RWBoolean.No)]
    public long Timestamp => (long)(DateTime.Now.ToUniversalTime() - new DateTime(1970, 1, 1)).TotalMilliseconds;
}

尝试了试用FastObjectRW.DefaultOptions &= ~FastObjectRWOptions.CannotSetException;或者[RWObject(CannotSetException = RWBoolean.No)]都不行,均会引发异常

序列化 double 类型存在的精度问题

static void Main(string[] args)
{
    var d1 = "Hello World";
    var d2 = new DateTime();
    var d3 = 3;
    var d4 = 3.1415926;
    var d5 = true;

    var obj = new ApiResultPager<object>()
    {
        PageSize = 10,
        PageIndex = 1,
        PageCount = 5,
        Total = 11,
        Data = new List<object>() { d1, d2, d3, d4, d5 }
    };

    var json1 = Swifter.Json.JsonFormatter.SerializeObject(obj);
    var json2 = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
    var json3 = Swifter.Json.JsonFormatter.SerializeObject(3.1415926m);

    Console.WriteLine(json1);
    Console.WriteLine();
    Console.WriteLine(json2);
    Console.WriteLine();
    Console.WriteLine(json3);

    Console.ReadKey();
}

控制台输出内容为:

{"code":200,"ps":10,"pi":1,"pc":5,"total":11,"data":["Hello World","0001/01/01 00:00:00",3,3.1415926000000001,true],"timestamp":1570551315742}

{"code":200,"ps":10,"pi":1,"pc":5,"total":11,"data":["Hello World","0001/01/01 00:00:00",3,3.1415926,true],"timestamp":1570551315922}

3.1415926

自定义日期格式有bug,对属性字段中的日期类型无效

通过jsonFormatter.SetDateTimeFormat("yyyy-MM-dd HH:mm:ss");设置的日期格式,只对自身是DateTime的对象才有效,任何自定义类的属性或字段,再或者字典值,都无效,示例就用了最基本的DateTime变量做了演示,实际怎么可能有这种json对象?

关于JsonFormatterOptions.IgnoreNull和dynamic内包含日期的序列化

首先我定义了一个类,用来返回数据

class ApiResult
{
    [RWField(Name = "code", Order = 1)]
    public int Code { get; set; }

    [RWField(Name = "msg", Order = 2)]
    public string Message { get; set; }

    [RWField(Name = "timestamp", Order = 3)]
    public long Timestamp => (long)(DateTime.Now.ToUniversalTime() - new DateTime(1970, 1, 1)).TotalMilliseconds;

    public static ApiResult Succeed() => new ApiResult { Code = 200 };
    public static ApiResult Failed(int code, string errorMessage) 
        => new ApiResult { Code = code, Message= errorMessage };
}

class ApiResult<T> : ApiResult
{
    public T Data { get; set; }

    public static ApiResult<T> Succeed(T data) => new ApiResult<T> { Code = 200, Data = data };
}

定义了一个用来测试的类

class Student
{
    public int No { get; set; }

    public string Name { get; set; }

    public string Addr { get; set; }

    [RWFormat("yyyy-MM-dd HH:mm:ss")]
    public DateTime Birthday { get; set; }
}

测试程序

class Program
{
    static void Main(string[] args)
    {
        var result1 = ApiResult<Student>.Succeed(new Student() { No = 1, Name = "张三", Addr = null, Birthday = DateTime.Now });
        var json1 = JsonFormatter.SerializeObject(result1);
        var json2 = JsonFormatter.SerializeObject(result1, JsonFormatterOptions.IgnoreNull);

        var result2 = ApiResult.Failed(400, "网络连接错误");
        var json3 = JsonFormatter.SerializeObject(result2);
        var json4 = JsonFormatter.SerializeObject(result2, JsonFormatterOptions.IgnoreNull);

        var stu = new { No = 1, Name = "张三", Addr = default(string), Birthday = DateTime.Now };
        var json5 = JsonFormatter.SerializeObject(ApiResult<dynamic>.Succeed(stu));

        Console.WriteLine(json1);
        Console.WriteLine(json2);
        Console.WriteLine(json3);
        Console.WriteLine(json4);
        Console.WriteLine(json5);

        Console.ReadKey();
    }
}

输出结果如下:

// json1
{"code":200,"msg":null,"timestamp":1563418324151,"Data":{"Addr":null,"Birthday":"2019-07-18 10:52:03","Name":"张三","No":1}}

// json2
{"code":200,"timestamp":1563418324195,"Data":{"Birthday":"2019-07-18 10:52:03","Name":"张三","No":1}}

// json3
{"code":400,"msg":"网络连接错误","timestamp":1563418324205}

// json4
{"code":400,"msg":"网络连接错误","timestamp":1563418324206}

// json5
{"code":200,"msg":null,"timestamp":1563418324213,"Data":{"Addr":null,"Birthday":"2019-07-18T10:52:04.206+08:00","Name":"张三","No":1}}

对比json1,json2这两个,其实更期望序列化后得到的结果为如下字符串:
{"code":200,"timestamp":1563418324151,"Data":{"Addr":null,"Birthday":"2019-07-18 10:52:03","Name":"张三","No":1}}

目前 JsonFormatterSerializeObject<T>(T value, JsonFormatterOptions options)方法在设置 options 为 JsonFormatterOptions.IgnoreNull时,会导致对象内所有为null的属性被忽略,无法得到上面期望的结果。

是否可以在RWFieldAttribute中增加对于是否忽略属性的功能支持(当类中某个属性标记为不忽略时,即便options=JsonFormatterOptions.IgnoreNull也不忽略此属性)

另外,对于json5,动态类型中的DateTime,序列化时如何设置指定格式呢?

The timezone offset is being serialized incorrectly for date/times

I have a DateTime that is in UTC-6 timezone, which serializes like this in other serializers:
"2020-06-01T00:00:00-06:00"

Using Swifter.Json, it serializes as:
"2020-06-01T00:00:00-07:00"
...which happens to be my local timezone, but not the timezone of the DateTime I'm giving it.

Swifter.Json 序列化 enum 和 DateTime 不正确的问题

  • 测试环境:.NET Core 3.0 Preview 9
  • Package 版本:Swfiter.Json v1.2.9.5 & Swifter.Extensions.AspNetCore v1.2.9.5

问题如下:

  • 序列化 enum 时,序列化的结果是枚举的属性名称,而不是属性的值;
  • 序列化 DateTime 时,序列化的结果是 DateTimeOffset 的值,而不是 DateTime 的值,带有时区信息;

首字母小写

Swifter.json 有没有快速的设置 将序列化类的首字母小写

unity il2cpp 报错

unity IL2CPP error for method 'System.Void Swifter.Json.JsonFormatter::Swifter.RW.ITargetedBind.Make

生态

大哥,你这性能确实高,但是SpanJson有AspNetCore插件,你赶紧跟上啊,一个小小的库也得有生态啊
有生态才有流行度,先让它火起来

Deserialize Type DateTime? Exception

var result = Swifter.Json.JsonFormatter.DeserializeObject<DateTime?>("");
Throw Exception
Value cannot be null.
Parameter name: chars

Why not return null
Another issue
Class contains field

[Swifter.RW.RWFormat("yyyy-MM-dd")]
public DateTime? time { get; set; }

SerializeObject Throw Exception
Field type 'System.Nullable`1[System.DateTime]' does not implement 'System.IFormattable' interface.

Support F# data structures

Hi. Would be cool to have a support for typical F# data structures like these:

  • Option
  • List
  • Discriminated unions
  • One-Case discriminated unions
  • Measure units

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.