GVKun编程网logo

如何使用Newtonsoft JSON.NET执行提供“路径”的部分对象序列化(对象实现序列化接口)

12

对于如何使用NewtonsoftJSON.NET执行提供“路径”的部分对象序列化感兴趣的读者,本文将提供您所需要的所有信息,我们将详细讲解对象实现序列化接口,并且为您提供关于.netcore3.1we

对于如何使用Newtonsoft JSON.NET执行提供“路径”的部分对象序列化感兴趣的读者,本文将提供您所需要的所有信息,我们将详细讲解对象实现序列化接口,并且为您提供关于.net core3.1 web api中使用newtonsoft替换掉默认的json序列化组件、.net core使用Newtonsoft.Json进行序列化处理解决返回值首字母小写、.Net使用Newtonsoft.Json.dll(JSON.NET)对象序列化成json、反序列化json示例教程、c# – 使用Newtonsoft.Json反序列化DbGeometry的宝贵知识。

本文目录一览:

如何使用Newtonsoft JSON.NET执行提供“路径”的部分对象序列化(对象实现序列化接口)

如何使用Newtonsoft JSON.NET执行提供“路径”的部分对象序列化(对象实现序列化接口)

我遇到的情况是我有一个非常大的C#对象,但是,我只需要返回一些属性(可以在嵌套对象上),允许客户端JavaScript修改这些属性,然后发送结果对象返回服务器以执行就地部分反序列化。

这个想法是重新使用一些非常大的现有业务对象,但是只对序列化并将那些属性仅发送回客户端应用程序进行修改(以使传输的数据量保持最小)是明智的。

我基本上有一个XML文件,在其中我使用“路径语法”预定义了所有绑定,该路径仅指示需要序列化的那些属性。因此,我可以使用“
WorkOrder.UserField1”或“ WorkOrder.Client.Name”之类的东西。

我尝试使用自定义合同解析器来确定是否应序列化属性;但是,似乎我没有关于“路径”的信息(换句话说,对象在链中的其他属性建模),以确定该属性是否应该序列化。

我也尝试过使用自定义的JsonTextWriter,但是即使有Path属性可用,我似乎也无法覆盖跟踪路径所必需的方法。为了能够查看要序列化的属性的路径层次结构并通过查找表中的路径并做出决定来确定是否应该序列化的属性,我是否可能忽略了一些简单的事情?

答案1

小编典典

这里的基本困难是Json.NET是基于契约的序列化器,它为要序列化的每种 类型
创建契约,然后根据契约对序列进行(反)序列化。如果类型出现在对象层次结构的多个位置,则适用相同的合同。但是您要根据给定类型在层次结构中的位置有选择地包括属性,这与基本的“一种类型一个合同”设计冲突。

解决此问题的一种快速方法是将序列化为JObject,然后JToken.SelectTokens()仅选择要返回的JSON数据,然后删除其他所有内容。由于SelectTokens完全支持JSONPath查询语法,因此您可以有选择地包括使用数组和属性通配符或其他过滤器,例如:

"$.FirstLevel[*].Bar"

包括"Bar"在以"FirstLevel"根对象命名的属性的所有数组成员中命名的所有属性。

这样可以减少所需的网络使用量,但不会节省服务器上的任何处理时间。

可以通过以下扩展方法完成删除:

public static partial class JsonExtensions{    public static TJToken RemoveAllExcept<TJToken>(this TJToken obj, IEnumerable<string> paths) where TJToken : JToken    {        if (obj == null || paths == null)            throw new NullReferenceException();        var keepers = new HashSet<JToken>(paths.SelectMany(path => obj.SelectTokens(path)), ObjectReferenceEqualityComparer<JToken>.Default);        var keepersAndParents = new HashSet<JToken>(keepers.SelectMany(t => t.AncestorsAndSelf()), ObjectReferenceEqualityComparer<JToken>.Default);        // Keep any token that is a keeper, or a child of a keeper, or a parent of a keeper        // I.e. if you have a path ""$.A.B" and it turns out that B is an object, then everything        // under B should be kept.        foreach (var token in obj.DescendantsAndSelfReversed().Where(t => !keepersAndParents.Contains(t) && !t.AncestorsAndSelf().Any(p => keepers.Contains(p))))            token.RemoveFromLowestPossibleParent();        // Return the object itself for fluent style programming.        return obj;    }    public static string SerializeAndSelectTokens<T>(T root, string[] paths, Formatting formatting = Formatting.None, JsonSerializerSettings settings = null)    {        var obj = JObject.FromObject(root, JsonSerializer.CreateDefault(settings));        obj.RemoveAllExcept(paths);        var json = obj.ToString(formatting);        return json;    }    public static TJToken RemoveFromLowestPossibleParent<TJToken>(this TJToken node) where TJToken : JToken    {        if (node == null)            return null;        JToken toRemove;        var property = node.Parent as JProperty;        if (property != null)        {            // Also detach the node from its immediate containing property -- Remove() does not do this even though it seems like it should            toRemove = property;            property.Value = null;        }        else        {            toRemove = node;        }        if (toRemove.Parent != null)            toRemove.Remove();        return node;    }    public static IEnumerable<JToken> DescendantsAndSelfReversed(this JToken node)    {        if (node == null)            throw new ArgumentNullException();        return RecursiveEnumerableExtensions.Traverse(node, t => ListReversed(t as JContainer));    }    // Iterate backwards through a list without throwing an exception if the list is modified.    static IEnumerable<T> ListReversed<T>(this IList<T> list)    {        if (list == null)            yield break;        for (int i = list.Count - 1; i >= 0; i--)            yield return list[i];    }}public static partial class RecursiveEnumerableExtensions{    // Rewritten from the answer by Eric Lippert https://stackoverflow.com/users/88656/eric-lippert    // to "Efficient graph traversal with LINQ - eliminating recursion" http://stackoverflow.com/questions/10253161/efficient-graph-traversal-with-linq-eliminating-recursion    // to ensure items are returned in the order they are encountered.    public static IEnumerable<T> Traverse<T>(        T root,        Func<T, IEnumerable<T>> children)    {        yield return root;        var stack = new Stack<IEnumerator<T>>();        try        {            stack.Push((children(root) ?? Enumerable.Empty<T>()).GetEnumerator());            while (stack.Count != 0)            {                var enumerator = stack.Peek();                if (!enumerator.MoveNext())                {                    stack.Pop();                    enumerator.Dispose();                }                else                {                    yield return enumerator.Current;                    stack.Push((children(enumerator.Current) ?? Enumerable.Empty<T>()).GetEnumerator());                }            }        }        finally        {            foreach (var enumerator in stack)                enumerator.Dispose();        }    }}/// <summary>/// A generic object comparerer that would only use object''s reference, /// ignoring any <see cref="IEquatable{T}"/> or <see cref="object.Equals(object)"/>  overrides./// </summary>public class ObjectReferenceEqualityComparer<T> : IEqualityComparer<T> where T : class{    // Adapted from this answer https://stackoverflow.com/a/1890230    // to https://stackoverflow.com/questions/1890058/iequalitycomparert-that-uses-referenceequals    // By https://stackoverflow.com/users/177275/yurik    private static readonly IEqualityComparer<T> _defaultComparer;    static ObjectReferenceEqualityComparer() { _defaultComparer = new ObjectReferenceEqualityComparer<T>(); }    public static IEqualityComparer<T> Default { get { return _defaultComparer; } }    #region IEqualityComparer<T> Members    public bool Equals(T x, T y)    {        return ReferenceEquals(x, y);    }    public int GetHashCode(T obj)    {        return System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(obj);    }    #endregion}

然后像这样使用它们:

public class TestClass{    public static void Test()    {        var root = new RootObject        {            FirstLevel1 = new FirstLevel            {                SecondLevel1 = new List<SecondLevel> { new SecondLevel { A = "a11", B = "b11", Third1 = new ThirdLevel { Foo = "Foos11", Bar = "Bars11" }, Third2 = new List<ThirdLevel> { new ThirdLevel { Foo = "FooList11", Bar = "BarList11" } } } },                SecondLevel2 = new List<SecondLevel> { new SecondLevel { A = "a12", B = "b12", Third1 = new ThirdLevel { Foo = "Foos12", Bar = "Bars12" }, Third2 = new List<ThirdLevel> { new ThirdLevel { Foo = "FooList12", Bar = "BarList12" } } } },            },            FirstLevel2 = new FirstLevel            {                SecondLevel1 = new List<SecondLevel> { new SecondLevel { A = "a21", B = "b21", Third1 = new ThirdLevel { Foo = "Foos21", Bar = "Bars21" }, Third2 = new List<ThirdLevel> { new ThirdLevel { Foo = "FooList21", Bar = "BarList21" } } } },                SecondLevel2 = new List<SecondLevel> { new SecondLevel { A = "a22", B = "b22", Third1 = new ThirdLevel { Foo = "Foos22", Bar = "Bars22" }, Third2 = new List<ThirdLevel> { new ThirdLevel { Foo = "FooList22", Bar = "BarList22" } } } },            }        };        Assert.IsTrue(JObject.FromObject(root).DescendantsAndSelf().OfType<JValue>().Count() == 24); // No assert        var paths1 = new string[]         {            "$.FirstLevel2.SecondLevel1[*].A",            "$.FirstLevel1.SecondLevel2[*].Third2[*].Bar",        };        Test(root, paths1, 2);        var paths3 = new string[]         {            "$.FirstLevel1.SecondLevel2[*].Third2[*].Bar",        };        Test(root, paths3, 1);        var paths4 = new string[]         {            "$.*.SecondLevel2[*].Third2[*].Bar",        };        Test(root, paths4, 2);    }    static void Test<T>(T root, string [] paths, int expectedCount)    {        var json = JsonExtensions.SerializeAndSelectTokens(root, paths, Formatting.Indented);        Console.WriteLine("Result using paths: {0}", JsonConvert.SerializeObject(paths));        Console.WriteLine(json);        Assert.IsTrue(JObject.Parse(json).DescendantsAndSelf().OfType<JValue>().Count() == expectedCount); // No assert    }}public class ThirdLevel{    public string Foo { get; set; }    public string Bar { get; set; }}public class SecondLevel{    public ThirdLevel Third1 { get; set; }    public List<ThirdLevel> Third2 { get; set; }    public string A { get; set; }    public string B { get; set; }}public class FirstLevel{    public List<SecondLevel> SecondLevel1 { get; set; }    public List<SecondLevel> SecondLevel2 { get; set; }}public class RootObject{    public FirstLevel FirstLevel1 { get; set; }    public FirstLevel FirstLevel2 { get; set; }}

请注意,有一个增强功能请求:ADD
JsonProperty.ShouldSerialize(对象目标,字符串路径)#1857,可以更轻松地启用这种功能。

演示在这里和这里摆弄。

.net core3.1 web api中使用newtonsoft替换掉默认的json序列化组件

.net core3.1 web api中使用newtonsoft替换掉默认的json序列化组件

在微软的文档中,有着较为详细的替换教程

https://docs.microsoft.com/zh-cn/aspnet/core/web-api/advanced/formatting?view=aspnetcore-3.1

但是微软的文档并不算太详细,对于新手而言,着实不算太友好。以下是我基于微软给出的方案,列出的更为详尽的方案。

第一步,引入包

 

 第二步,修改sartups.cs中的 ConfigureServices

在web api项目中,加入以下代码:

 

#region newtonsoft
.AddNewtonsoftJson(options =>
{
//修改属性名称的序列化方式,首字母小写
options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();

//修改时间的序列化方式
options.SerializerSettings.Converters.Add(new IsoDateTimeConverter() { DateTimeFormat = "yyyy/MM/dd HH:mm:ss" });
}
);
#endregion

 

 至此,替换步骤结束。

接下来,让我们看一下是否是真的替换成功。

首先,在控制器里,添加一个get方法,输出类型为jsonresult

 

在GetCartInfo方法中,返回类型如下

 

 这是标准的C#命名方式,而我们前面配置的newtonsoft中,将属性首字母设置为了小写

 接下来运行项目,使用postman测试接口,测试结果如下:

 

 

 

 可以发现,接收到的json数据中,所有名称都是小写开头,说明我们前面的配置已经生效。

至此,替换成功。

 

.net core使用Newtonsoft.Json进行序列化处理解决返回值首字母小写

.net core使用Newtonsoft.Json进行序列化处理解决返回值首字母小写

var response = context.HttpContext.Response;
            response.ContentType = "application/json";
            var setting=new JsonSerializerSettings();
            setting.ContractResolver = new CamelCasePropertyNamesContractResolver();  //使用驼峰样式
            var result = JsonConvert.SerializeObject(Data,setting);
            response.WriteAsync(result);

我对返回进行了封装,所以配置只能加在序列化这里,全局加的不起作用。驼峰样式首字母是小写的。

全局加配置

services.AddMvc().AddJsonOptions(options =>
        {
            //忽略循环引用
            options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
            //不使用驼峰样式的key
            options.SerializerSettings.ContractResolver = new DefaultContractResolver();
            //设置时间格式
            options.SerializerSettings.DateFormatString = "yyyy-MM-dd";
        });

 

 

.Net使用Newtonsoft.Json.dll(JSON.NET)对象序列化成json、反序列化json示例教程

.Net使用Newtonsoft.Json.dll(JSON.NET)对象序列化成json、反序列化json示例教程

JSON作为一种轻量级的数据交换格式,简单灵活,被很多系统用来数据交互,作为一名.NET开发人员,JSON.NET无疑是最好的序列化框架,支持XML和JSON序列化,高性能,免费开源,支持LINQ查询。目前已被微软集成于webapi框架之中,因此,熟练掌握JSON.NET相当重要,这篇文章是零度参考官网整理的示例,通过这些示例,可以全面了解JSON.NET提供的功能。

Newtonsoft.Json的地址:

官网:http://json.codeplex.com/

源码地址:https://github.com/JamesNK/Newtonsoft.Json

Newtonsoft.Json.dll下载:https://github.com/JamesNK/Newtonsoft.Json/releases

1、使用Newtonsoft.Json(JSON.NET)序列化对象,通过Newtonsoft.Json.Formatting将json格式化输出。

            Account account = new Account
            {
                Email = "1930906722@qq.com",Active = true,CreatedDate =DateTime.Now,Roles = new List<string> { "User","Admin" }
            };
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(account,Newtonsoft.Json.Formatting.Indented);
            Console.WriteLine(json);
    public class Account
    {
        public string Name { get; set; }
        public string Email { get; set; }
        public bool Active { get; set; }
        public DateTime CreatedDate { get; set; }
        public IList<string> Roles { get; set; }
    }

执行结果:

2、使用Newtonsoft.Json(JSON.NET)序列化List集合:

            List<string> videogames = new List<string> { "HTML5","JavaScript",".net","c#",".net core" };
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(videogames);
            Console.WriteLine(json);

执行结果:

3、使用Newtonsoft.Json(JSON.NET)序列化dictionary字典

            System.Collections.Generic.Dictionary<string,string> dic = new System.Collections.Generic.Dictionary<string,string>
            {
                { "Name","张三" },{ "Age","20" },{ "Email","193090622@qq.com" }
            };
            string json1 = Newtonsoft.Json.JsonConvert.SerializeObject(dic,Newtonsoft.Json.Formatting.Indented);
            Console.WriteLine(json1);
            Console.WriteLine("");
            Console.WriteLine("未格式化的json:");
            string json2 = Newtonsoft.Json.JsonConvert.SerializeObject(dic,Newtonsoft.Json.Formatting.None);
            Console.WriteLine(json2);

执行结果:

4、Newtonsoft.Json(JSON.NET)将序列化结果保存到指定的文件:

            User movie = new User { Name = "张三",Age = 1993 };
            using (System.IO.StreamWriter file = System.IO.File.CreateText(@"F:\UserInfo.txt"))
            {
                Newtonsoft.Json.JsonSerializer serializer = new Newtonsoft.Json.JsonSerializer();
                serializer.Serialize(file,movie);
            }
    public class User
    {
        public string Name { set; get; }
        public int Age { set; get; }
    }

执行后保存到文件的结果:

5、Newtonsoft.Json(JSON.NET)基于枚举类型的JsonConverters转换器

            List<JosnEnum> list = new List<JosnEnum> { JosnEnum.NotStartus,JosnEnum.Startus };
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(list);
            Console.WriteLine(json);
            Console.WriteLine("");

            System.Collections.Generic.Dictionary<string,int> dic = new System.Collections.Generic.Dictionary<string,int>
            { 
            {((JosnEnum)(int)JosnEnum.NotStartus).ToString(),(int)JosnEnum.NotStartus},{((JosnEnum)(int)JosnEnum.Startus).ToString(),(int)JosnEnum.Startus}
            };
            string dicJson = Newtonsoft.Json.JsonConvert.SerializeObject(dic);
            Console.WriteLine(dicJson);

            Console.WriteLine("");
            List<JosnEnum> list2 = new List<JosnEnum>
            {
                JosnEnum.NotStartus,JosnEnum.Startus
            };
            string json3 = Newtonsoft.Json.JsonConvert.SerializeObject(list2,new Newtonsoft.Json.Converters.StringEnumConverter());
            Console.WriteLine(json3);

            Console.WriteLine("");

            List<JosnEnum> result = Newtonsoft.Json.JsonConvert.DeserializeObject<List<JosnEnum>>(json3,new Newtonsoft.Json.Converters.StringEnumConverter());
            Console.WriteLine(string.Join(",",result.Select(c => c.ToString())));
    public enum JosnEnum
    {
        NotStartus = 0,Startus = 1
    }

执行结果:

6、Newtonsoft.Json(JSON.NET)通过JRaw将JS函数序列化到JSON中

            JavaScriptSettings settings = new JavaScriptSettings
            {
                OnLoadFunction = new Newtonsoft.Json.Linq.JRaw("OnLoad"),OnSucceedFunction = new Newtonsoft.Json.Linq.JRaw("function(e) { alert(e); }")
            };
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(settings,Newtonsoft.Json.Formatting.Indented);
            Console.WriteLine(json);
    public class JavaScriptSettings
    {
        public Newtonsoft.Json.Linq.JRaw OnLoadFunction { get; set; }
        public Newtonsoft.Json.Linq.JRaw OnSucceedFunction { get; set; }
    }

7、使用Newtonsoft.Json(JSON.NET)将json反序列化对象

  string json = @"{
   'Email': '1930906722@qq.com','Active': true,'CreatedDate': '2016-11-26 20:39','Roles': [
     'User','Admin'
]
 }";
            Account account = Newtonsoft.Json.JsonConvert.DeserializeObject<Account>(json);
            Console.WriteLine(account.Email);
    public class Account
    {
        public string Name { get; set; }
        public string Email { get; set; }
        public bool Active { get; set; }
        public DateTime CreatedDate { get; set; }
        public IList<string> Roles { get; set; }
    }

执行结果:

8、使用Newtonsoft.Json(JSON.NET)反序列化List集合:

            string json = @"['Html5','C#','.Net','.Net Core']";
            List<string> videogames = Newtonsoft.Json.JsonConvert.DeserializeObject<List<string>>(json);
            Console.WriteLine(string.Join(",videogames));

执行结果:

9、使用Newtonsoft.Json(JSON.NET)反序列化dictionary字典

            string json = @"{'Name': '张三','Age': '23'}";
            var htmlAttributes = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string,string>>(json);
            Console.WriteLine(htmlAttributes["Name"]);
            Console.WriteLine(htmlAttributes["Age"]);

执行结果:

10、使用Newtonsoft.Json(JSON.NET)序列化var匿名类型,有时候,我们并不需要先定义一个类,然后new一个对象后再进行序列化,JSON.NET支持匿名类型的序列化和反序列化。

            var test1 = new { Name = "李四",Age = 26 };
            var json = Newtonsoft.Json.JsonConvert.SerializeObject(test1);
            Console.WriteLine(json);

            Console.WriteLine("");
            var test2 = new { Name = "",Age = 0 };
            string json1 = @"{'Name':'张三','Age':'25'}";
            var result = Newtonsoft.Json.JsonConvert.DeserializeAnonymousType(json1,test2);
            Console.WriteLine(result.Name);

执行结果:

11、Newtonsoft.Json(JSON.NET)用新JSON字符串填充指定对象的属性值

            Account account = new Account
            {
                Email = "1930906722@qq.com",CreatedDate = DateTime.Now,"Admin" }
            };
            string json = @"{'Active': false,'Roles': ['Expired']}";
            Newtonsoft.Json.JsonConvert.PopulateObject(json,account);
            Console.WriteLine(account.Active);
            Console.WriteLine(account.Email);
    public class Account
    {
        public string Name { get; set; }
        public string Email { get; set; }
        public bool Active { get; set; }
        public DateTime CreatedDate { get; set; }
        public IList<string> Roles { get; set; }
    }

执行结果:

12、使用Newtonsoft.Json(JSON.NET)反序列化时可指定构造函数:

首先我们定义如下的类型,我们希望JSON.NET反序列化对象时使用第2个构造函数,我们将第一个默认构造函数屏蔽,标记为私有private修饰符。第2个构造函数需要指定一个website对象作为参数,如果提供的参数为null则抛出异常:

public class Website
{
    public string Url { get; set; }
    private Website()
    {
    }
    public Website(Website website)
    {
        if (website == null) throw new ArgumentNullException("website");
        Url = website.Url;
    }
}

现在使用一般的方式反序列化一个JSON字符串。执行出现的结果:

我们发现该序列化方法抛出了异常,并没有按照我们预想的方式进行反序列化,JSON.NET提供如下的方式指定公有构造函数。

            string json = @"{'Url':'http://www.cnblogs.com/linJie1930906722/'}";
            Website website = Newtonsoft.Json.JsonConvert.DeserializeObject<Website>(json,new Newtonsoft.Json.JsonSerializerSettings
            {
                ConstructorHandling = Newtonsoft.Json.ConstructorHandling.AllowNonPublicDefaultConstructor
            });
            Console.WriteLine(website.Url);

执行结果:

另外,JSON.NET提供了指定任何构造函数的JsonConstructorAttribute特性,只需要在构造函数上标记,即可指定构造函数。

    public class Users
    {
        public string UserName { get; private set; }
        public bool Enabled { get; private set; }
        public Users()
        {
        }
        [Newtonsoft.Json.JsonConstructor]
        public Users(string userName,bool enabled)
        {
            UserName = userName;
            Enabled = enabled;
        }
    }
            string json = @"{""UserName"": ""希特勒"",""Enabled"": true}";
            Users user = Newtonsoft.Json.JsonConvert.DeserializeObject<Users>(json);
            Console.WriteLine(user.UserName);

执行结果:

13、当对象的属性为默认值(0或null)时不序列化该属性

    public class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public Person Partner { get; set; }
        public decimal? Salary { get; set; }
    }
            Person person1 = new Person();
            string json1 = Newtonsoft.Json.JsonConvert.SerializeObject(person1,Newtonsoft.Json.Formatting.Indented,new Newtonsoft.Json.JsonSerializerSettings
            {
                DefaultValueHandling = Newtonsoft.Json.DefaultValueHandling.Ignore
            });
            Console.WriteLine(json1);

            Console.WriteLine("");
            Person person2 = new Person(){Name = "奥巴马"};
            string json2 = Newtonsoft.Json.JsonConvert.SerializeObject(person2,new Newtonsoft.Json.JsonSerializerSettings
            {
                DefaultValueHandling = Newtonsoft.Json.DefaultValueHandling.Ignore
            });
            Console.WriteLine(json2);

执行结果:

14、Newtonsoft.Json(JSON.NET)中忽略null值得处理器

    public class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public Person Partner { get; set; }
        public decimal? Salary { get; set; }
    }
            Person person = new Person { Name = "张三",Age = 46 };
            string jsonIncludeNullValues = Newtonsoft.Json.JsonConvert.SerializeObject(person,Newtonsoft.Json.Formatting.Indented);
            Console.WriteLine(jsonIncludeNullValues);
            Console.WriteLine("");
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(person,new Newtonsoft.Json.JsonSerializerSettings
            {
                NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore
            });
            Console.WriteLine(json);

执行结果:

15、JSON.NET中循环引用的处理方法

            Employee employee1 = new Employee { Name = "张三" };
            Employee employee2 = new Employee { Name = "李四" };
            employee1.Manager = employee2;
            employee2.Manager = employee2;
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(employee1,new Newtonsoft.Json.JsonSerializerSettings
            {
                ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
            });
            Console.WriteLine(json);
    public class Employee
    {
        public string Name { get; set; }
        public Employee Manager { get; set; }
    }

执行结果:

16、通过ContractResolver指定属性名首字母小写,通常,在.NET中属性采用PascalCase规则(首字母大写),在JavaScript中属性名使用CamelCase规则(首字母小写),我们希望序列化后的JSON字符串符合CamelCase规则,JSON.NET提供的ContractResolver可以设置属性名小写序列化

    public class User
    {
        public string Name { set; get; }
        public int Age { set; get; }
    }
            User person = new User { Name = "张三",Age =52 };
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(person,new Newtonsoft.Json.JsonSerializerSettings
            {
                ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver()
            });
            Console.WriteLine(json);

执行结果:

17、JSON.NET中通过特性序列化枚举类型

    public enum ProductStatus
    { 
        NotConfirmed,Active,Deleted
    }

    public class Product
    {
        public string Name { get; set; }

        [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
        public ProductStatus Status { get; set; }
    }
            Product user = new Product { Name = @"羽绒服",Status = ProductStatus.Deleted };
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(user,Newtonsoft.Json.Formatting.Indented);
            Console.WriteLine(json);

执行结果:

18、指定需要序列化的属性

    [Newtonsoft.Json.JsonObject(Newtonsoft.Json.MemberSerialization.OptIn)]
    public class Categroy
    {
        //Id不需要序列化
        public Guid Id { get; set; }

        [Newtonsoft.Json.JsonProperty]
        public string Name { get; set; }

        [Newtonsoft.Json.JsonProperty]
        public int Size { get; set; }
    }
            Categroy categroy = new Categroy
            {
                Id = Guid.NewGuid(),Name = "内衣",Size = 52
            };
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(categroy,Newtonsoft.Json.Formatting.Indented);
            Console.WriteLine(json);

执行结果:

19、序列化对象时指定属性名

    public class Videogame
    {
        [Newtonsoft.Json.JsonProperty("name")]
        public string Name { get; set; }

        [Newtonsoft.Json.JsonProperty("release_date")]
        public DateTime ReleaseDate { get; set; }
    }
            Videogame starcraft = new Videogame
            {
                Name = "英雄联盟",ReleaseDate = DateTime.Now
            };
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(starcraft,Newtonsoft.Json.Formatting.Indented);
            Console.WriteLine(json);

执行结果:

20、序列化时指定属性在JSON中的顺序

    public class Personl
    {
        [Newtonsoft.Json.JsonProperty(Order = 2)]
        public string FirstName { get; set; }

        [Newtonsoft.Json.JsonProperty(Order = 1)]
        public string LastName { get; set; }
    }
            Personl person = new Personl { FirstName = "张三",LastName = "李四" };
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(person,Newtonsoft.Json.Formatting.Indented);
            Console.WriteLine(json);

执行结果:

21、反序列化指定属性是否必须有值必须不为null,在反序列化一个JSON时,可通过JsonProperty特性的required指定反序列化行为,当反序列化行为与指定的行为不匹配时,JSON.NET将抛出异常,required是枚举,required.Always表示属性必须有值切不能为null,required.AllowNull表示属性必须有值,但允许为null值。

    public class Order
    {
        [Newtonsoft.Json.JsonProperty(required = Newtonsoft.Json.required.Always)]
        public string Name { get; set; }

        [Newtonsoft.Json.JsonProperty(required = Newtonsoft.Json.required.AllowNull)]
        public DateTime? ReleaseDate { get; set; }
    }
            string json = @"{
    'Name': '促销订单','ReleaseDate': null
  }";
            Order order = Newtonsoft.Json.JsonConvert.DeserializeObject<Order>(json);
            Console.WriteLine(order.Name);
            Console.WriteLine(order.ReleaseDate);

执行结果:

22、通过特性指定null值忽略序列化

    public class Vessel
    {
        public string Name { get; set; }

        [Newtonsoft.Json.JsonProperty(NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
        public DateTime? launchdate { get; set; }
    }
            Vessel vessel = new Vessel { Name = "张三" };
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(vessel,Newtonsoft.Json.Formatting.Indented);
            Console.WriteLine(json);

执行结果:

23、忽略不需要序列化的属性,并不是对象所有属性都要参与序列化,我们可以使用JsonIgnore特性排除不需要序列化的属性,下面示例中的PasswordHash将被忽略。

    public class Accounts
    {
        public string FullName { get; set; }
        public string EmailAddress { get; set; }
        [Newtonsoft.Json.JsonIgnore]
        public string PasswordHash { get; set; }
    }
            Accounts account = new Accounts
            {
                FullName = "admin",EmailAddress = "1930906722@qq.com",PasswordHash = "dfsfgerhtyhsasdhjyujtgwe454811sfsg8d"
            };
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(account);
            Console.WriteLine(json);

执行结果:

24、序列化或反序列化时指定日期时间格式,JSON.NET中提供一个名为JsonSerializerSettings的设置对象,可通过此对象设置很多序列化和反序列化的行为,如果要设置JSON.NET序列化输出的日期时间格式,只需要指定格式化字符串即可。通过JsonSerializerSettings的DateFormatString属性指定日期时间格式:

    public class Customer
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public DateTime CreateDate { get; set; }
    }
            Customer custom = new Customer { FirstName = "张三",LastName = "李四",CreateDate = DateTime.Now };
            Newtonsoft.Json.JsonSerializerSettings settings = new Newtonsoft.Json.JsonSerializerSettings
            {
                DateFormatString = "yyyy-MM-dd HH:mm:ss",Formatting = Newtonsoft.Json.Formatting.Indented
            };
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(custom,settings);
            Console.WriteLine(json);

执行结果:

c# – 使用Newtonsoft.Json反序列化DbGeometry

c# – 使用Newtonsoft.Json反序列化DbGeometry

我正在按照John Papa在他最新的PluralSight课程中概述的方法,使用Angular,Breeze和Web API 2构建SPA.

一切顺利,我可以将信息,更新,插入,删除回服务器.但是我使用的是空间类型,当我尝试更新具有空间类型的实体时,会得到以下错误

An exception of type ‘Newtonsoft.Json.JsonSerializationException’ occurred in
Newtonsoft.Json.dll but was not handled in user code

Additional information: Error getting value from ‘WellKNownValue’ on
‘System.Data.Entity.Spatial.DbGeometry’.

内部异常似乎指出,WellKNownValue为null,它不是,因为我已经检查发送到服务器的JSON,然后发送到Breeze ContextProvider并使用SaveChanges方法保存Well事实.

{
"entities": [
 {
  "TableKey": 2,"CaseName": "Mikhail Lermontov","StartDate": "2013-06-11T00:00:00Z","EndDate": null,"IsCurrent": true,"SRID": 109,"Shape": {
    "$id": "2","$type": "System.Data.Entity.Spatial.DbGeometry,EntityFramework","Geometry": {
      "$id": "3","$type": "System.Data.Entity.Spatial.DbGeometryWellKNownValue,"CoordinateSystemId": 2193,"WellKNownText": "polyGON ((1695943 5462665,1713098 5462665,1713098 5449659,1695943 5449659,1695943 5462665))"
    }
  },"SpillLocation": "Marlborough Sounds","Image": "http://www.nzmaritime.co.nz/images/lm5.jpg\r\n","DefaultBaseMapKey": 2,"__unmapped": {
    "isPartial": false
  },"entityAspect": {
    "entityTypeName": "DatSpillCase:#Osiris.Model","defaultResourceName": "DatSpillCases","entityState": "Modified","originalValuesMap": {
      "CaseName": "Mikhail Lermontov"
    },"autoGeneratedKey": {
      "propertyName": "TableKey","autoGeneratedKeyType": "Identity"
    }
  }
}
 ],"saveOptions": {}
}

所以我的问题是,可以在NewtonSoft库中反序列化DbGeometry类型,如果没有,那么有什么建议可以解决.

解决方法

System.Data.Spatial.DbGeometry不能很好地与Newtonsoft.Json

您需要创建一个JsonConverter来转换DbGeometry

public class DbGeometryConverter : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return objectType.IsAssignableFrom(typeof(string));
        }

        public override object ReadJson(JsonReader reader,Type objectType,object existingValue,JsonSerializer serializer)
        {
            JObject location = JObject.Load(reader);
            JToken token = location["Geometry"]["WellKNownText"];
            string value = token.ToString();

            DbGeometry converted = DbGeometry.polygonFromText(value,2193);
            return converted;
        }

        public override void WriteJson(JsonWriter writer,object value,JsonSerializer serializer)
        {
            // Base serialization is fine
            serializer.Serialize(writer,value);
        }
    }

然后在您的模型的属性上添加属性

[JsonConverter(typeof(DbGeometryConverter))]
public DbGeometry Shape { get; set; }

现在,当您点击BreezeController时,反序列化将由我们的新DbGeometryConverter处理.

希望它有帮助.

关于如何使用Newtonsoft JSON.NET执行提供“路径”的部分对象序列化对象实现序列化接口的介绍已经告一段落,感谢您的耐心阅读,如果想了解更多关于.net core3.1 web api中使用newtonsoft替换掉默认的json序列化组件、.net core使用Newtonsoft.Json进行序列化处理解决返回值首字母小写、.Net使用Newtonsoft.Json.dll(JSON.NET)对象序列化成json、反序列化json示例教程、c# – 使用Newtonsoft.Json反序列化DbGeometry的相关信息,请在本站寻找。

本文标签: