大佬教程收集整理的这篇文章主要介绍了Newtonsoft.Json 序列化踩坑之 IEnumerable,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
Newtonsoft.Json
序列化踩坑之 IEnumerable
Newtonsoft.Json
是 .NET 下最受欢迎 JSON 操作库,使用起来也是非常方便,有时候也可能会不小心就踩坑了,这次就踩了一个,坑是这样的,如果要序列化的对象实现了 IEnumerable
接口,Newtonsoft.Json
就会认为这个对象是一个数组。。然后遍历这个对象,输出其中的值,如果是一个@L_489_4@的类型而且还有其他属性,其他属性就会被忽略,序列化之后就会发生数据丢失。
在我的公用类库 WeihanLi.Common 有一个分页列表的Model:
在 1.0.21及之前版本是这样定义的 源码
using System;
using System.Collections;
using System.Collections.Generic;
namespace WeihanLi.Common.Models
{
/// <sumMary>
/// IPagedListModel
/// </sumMary>
/// <typeparam name="T">Type</typeparam>
public interface IPagedListModel<out T> : IReadOnlyList<T>
{
/// <sumMary>
/// Data
/// </sumMary>
IReadOnlyList<T> Data { get; }
/// <sumMary>
/// Pagenumber
/// </sumMary>
int Pagenumber { get; }
/// <sumMary>
/// PageSize
/// </sumMary>
int PageSize { get; }
/// <sumMary>
/// @R_261_10586@lDataCount
/// </sumMary>
int @R_261_10586@lCount { get; set; }
}
/// <inheritdoc />
/// <sumMary>
/// @L_363_10@model
/// </sumMary>
/// <typeparam name="T">Type</typeparam>
[serializable]
public class PagedListModel<T> : IPagedListModel<T>
{
public IReadOnlyList<T> Data { get; set; }
privatE int _pagenumber = 1;
public int Pagenumber
{
get => _pagenumber;
set
{
if (value > 0)
{
_pagenumber = value;
}
}
}
privatE int _pageSize = 10;
public int PageSize
{
get => _pageSize;
set
{
if (value > 0)
{
_pageSize = value;
}
}
}
privatE int _@R_261_10586@lCount;
public int @R_261_10586@lCount
{
get => _@R_261_10586@lCount;
set
{
if (value > 0)
{
_@R_261_10586@lCount = value;
}
}
}
public int PageCount => Convert.ToInt32(Math.Ceiling(_@R_261_10586@lCount * 1.0 / _pageSizE));
public IEnumerator<T> GetEnumerator()
{
return Data.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return Data.GetEnumerator();
}
public T this[int index] => Data[index];
public int count => Data.Count;
}
}
上面的这种定义相当于实现了 IEnumerable 接口,之所以实现这个接口,是因为可以直接遍历这个对象,不需要遍历这个对象的Data 属性上遍历,但是这样序列化的时候就会有问题, Pagenumber/PageSize/@R_261_10586@lPage 之类的信息序列化时就会丢失
不要实现 IEnumerable
接口就可以了,修改后的代码如下所示:
using System;
using System.Collections.Generic;
namespace WeihanLi.Common.Models
{
/// <sumMary>
/// IPagedListModel
/// </sumMary>
/// <typeparam name="T">Type</typeparam>
public interface IPagedListModel<out T>
{
/// <sumMary>
/// Data
/// </sumMary>
IReadOnlyList<T> Data { get; }
/// <sumMary>
/// Pagenumber
/// </sumMary>
int Pagenumber { get; }
/// <sumMary>
/// PageSize
/// </sumMary>
int PageSize { get; }
/// <sumMary>
/// @R_261_10586@lDataCount
/// </sumMary>
int @R_261_10586@lCount { get; set; }
}
/// <inheritdoc />
/// <sumMary>
/// @L_363_10@model
/// </sumMary>
/// <typeparam name="T">Type</typeparam>
[serializable]
public class PagedListModel<T> : IPagedListModel<T>
{
public IReadOnlyList<T> Data { get; set; }
privatE int _pagenumber = 1;
public int Pagenumber
{
get => _pagenumber;
set
{
if (value > 0)
{
_pagenumber = value;
}
}
}
privatE int _pageSize = 10;
public int PageSize
{
get => _pageSize;
set
{
if (value > 0)
{
_pageSize = value;
}
}
}
privatE int _@R_261_10586@lCount;
public int @R_261_10586@lCount
{
get => _@R_261_10586@lCount;
set
{
if (value > 0)
{
_@R_261_10586@lCount = value;
}
}
}
public int PageCount => Convert.ToInt32(Math.Ceiling(_@R_261_10586@lCount * 1.0 / _pageSizE));
public T this[int index] => Data[index];
public int count => Data.Count;
}
}
@H_772_38@Test
写个示例测试一下,原来的代码类型改为 PagedListModel1,测试代码如下:
PagedListModel1:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
namespace DotNetCoreSample.Test
{
public class PagedListModel1<T> : IEnumerable<T>
{
public IReadOnlyList<T> Data { get; set; }
privatE int _pagenumber = 1;
public int Pagenumber
{
get => _pagenumber;
set
{
if (value > 0)
{
_pagenumber = value;
}
}
}
privatE int _pageSize = 10;
public int PageSize
{
get => _pageSize;
set
{
if (value > 0)
{
_pageSize = value;
}
}
}
privatE int _@R_261_10586@lCount;
public int @R_261_10586@lCount
{
get => _@R_261_10586@lCount;
set
{
if (value > 0)
{
_@R_261_10586@lCount = value;
}
}
}
public int PageCount => Convert.ToInt32(Math.Ceiling(_@R_261_10586@lCount * 1.0 / _pageSizE));
public T this[int index] => Data[index];
public int count => Data.Count;
public IEnumerator<T> GetEnumerator()
{
return Data.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return Data.GetEnumerator();
}
}
}
测试代码:
var pagedListModel = new PagedListModel<int>()
{
Pagenumber = 2,PageSize = 2,@R_261_10586@lCount = 6,Data = new int[] {1,2},};
var pagedListModel1 = new PagedListModel1<int>()
{
Pagenumber = 2,Data = new int[] { 1,2 },};
Console.WriteLine($"pagedListModel:{JsonConvert.serializeObject(pagedListModel)},pagedListModel1:{JsonConvert.serializeObject(pagedListModel1)}");
output:
pagedListModel:{"Data":[1,2],"Pagenumber":2,"PageSize":2,"@R_261_10586@lCount":6,"PageCount":3,"Count":2},pagedListModel1:[1,2]
可以看到实现了 IEnumerable 接口的那个类序列化之后一些属性丢失了
查看 Newtonsoft.Json
源码 https://github.com/JamesNK/Newtonsoft.Json
,找到为什么实现了 IEnumerable
接口就会有问题,最后找到了这里 https://github.com/JamesNK/Newtonsoft.Json/blob/master/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs#L1218
可以看到只要实现了 IEnumerable
接口,就会被当作是一个Json 数组,foreach 遍历其中的元素,其他属性就会被忽略掉了,这就是为什么上面我们实现了 IEnumerable
接口的对象序列化之后发生属性丢失的原因。
以上是大佬教程为你收集整理的Newtonsoft.Json 序列化踩坑之 IEnumerable全部内容,希望文章能够帮你解决Newtonsoft.Json 序列化踩坑之 IEnumerable所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。