Json.Net学习笔记
通常當(dāng)用到大的Json文檔的時(shí)候,你可能只對(duì)其中的一小個(gè)片段信息感興趣。這種情況下你想把Json.Net轉(zhuǎn)換為.Net 對(duì)象就會(huì)讓人很困擾,因?yàn)槟惚仨殲镴son的整個(gè)結(jié)果定義一個(gè).Net的類。
使用Json.Net很容易避開這個(gè)問題。在把它們傳遞到Json.Net序列化器之前,你可以使用Linq to Json 提取Json中你想要序列化的一些片段。
?string googleSearchText = @"{
????????????????? ""responseData"": {
??????????????????? ""results"": [
????????????????????? {
??????????????????????? ""GsearchResultClass"": ""GwebSearch"",
??????????????????????? ""unescapedUrl"": ""http://en.wikipedia.org/wiki/Paris_Hilton"",
??????????????????????? ""url"": ""http://en.wikipedia.org/wiki/Paris_Hilton"",
??????????????????????? ""visibleUrl"": ""en.wikipedia.org"",
??????????????????????? ""cacheUrl"": ""http://www.google.com/search?q=cache:TwrPfhd22hYJ:en.wikipedia.org"",
??????????????????????? ""title"": ""<b>Paris Hilton</b> - Wikipedia, the free encyclopedia"",
??????????????????????? ""titleNoFormatting"": ""Paris Hilton - Wikipedia, the free encyclopedia"",
??????????????????????? ""content"": ""[1] In 2006, she released her debut album...""
????????????????????? },
????????????????????? {
??????????????????????? ""GsearchResultClass"": ""GwebSearch"",
??????????????????????? ""unescapedUrl"": ""http://www.imdb.com/name/nm0385296/"",
??????????????????????? ""url"": ""http://www.imdb.com/name/nm0385296/"",
??????????????????????? ""visibleUrl"": ""www.imdb.com"",
??????????????????????? ""cacheUrl"": ""http://www.google.com/search?q=cache:1i34KkqnsooJ:www.imdb.com"",
??????????????????????? ""title"": ""<b>Paris Hilton</b>"",
??????????????????????? ""titleNoFormatting"": ""Paris Hilton"",
??????????????????????? ""content"": ""Self: Zoolander. Socialite <b>Paris Hilton</b>...""
????????????????????? }
??????????????????? ],
??????????????????? ""cursor"": {
????????????????????? ""pages"": [
??????????????????????? {
????????????????????????? ""start"": ""0"",
????????????????????????? ""label"": 1
??????????????????????? },
??????????????????????? {
????????????????????????? ""start"": ""4"",
????????????????????????? ""label"": 2
??????????????????????? },
??????????????????????? {
????????????????????????? ""start"": ""8"",
????????????????????????? ""label"": 3
??????????????????????? },
??????????????????????? {
????????????????????????? ""start"": ""12"",
????????????????????????? ""label"": 4
??????????????????????? }
????????????????????? ],
????????????????????? ""estimatedResultCount"": ""59600000"",
????????????????????? ""currentPageIndex"": 0,
????????????????????? ""moreResultsUrl"": ""http://www.google.com/search?oe=utf8&ie=utf8...""
??????????????????? }
????????????????? },
????????????????? ""responseDetails"": null,
????????????????? ""responseStatus"": 200
??????????????? }";
??????????? JObject googleSearch = JObject.Parse(googleSearchText);
??????????? // get JSON result objects into a list
??????????? IList<JToken> results = googleSearch["responseData"]["results"].Children().ToList();
??????????? // serialize JSON results into .NET objects
??????????? IList<SearchResult> searchResults = new List<SearchResult>();
??????????? foreach (JToken result in results)
??????????? {
??????????????? SearchResult searchResult = JsonConvert.DeserializeObject<SearchResult>(result.ToString());
??????????????? searchResults.Add(searchResult);
??????????? }
??????????? // Title = <b>Paris Hilton</b> - Wikipedia, the free encyclopedia
??????????? // Content = [1] In 2006, she released her debut album...
??????????? // Url =?http://en.wikipedia.org/wiki/Paris_Hilton
??????????? // Title = <b>Paris Hilton</b>
??????????? // Content = Self: Zoolander. Socialite <b>Paris Hilton</b>...
??????????? // Url =?http://www.imdb.com/name/nm0385296/
為了解決多余的Json這個(gè)問題,Json.Net有一系列內(nèi)置的選項(xiàng)可以進(jìn)行調(diào)整。
->JsonIgnoreAttribute and DataMemberAttribute
默認(rèn)情況下,在Json創(chuàng)建的時(shí)候Json.Net會(huì)包含所有類級(jí)別的public屬性和字段。添加JsonIgnoreAttribute到屬性上,告訴序列化器序列化時(shí)跳過它。
?public class Car
??? {
??????? // included in JSON
??????? public string Model { get; set; }
??????? public DateTime Year { get; set; }
??????? public List<string> Features { get; set; }
??????? // ignored
??????? [JsonIgnore]
??????? public DateTime LastModified { get; set; }
??? }
如果類有很多屬性,你只想序列化它的一小部分,添加JsonIgore到所有其他的屬性上會(huì)比較冗余,也比較容易出錯(cuò)。有一種用來處理這種情況的方法,添加DataContractAttribute到類上,添加DataMemberAttribute到需要被序列化的屬性上。與使用JsonIgnoreAttribute的opt-out序列化相比,opt-in序列化僅僅你標(biāo)記的屬性被需列化。
using System.Runtime.Serialization;
? [DataContract]
??? public class Computer
??? {
??????? // included in JSON
??????? [DataMember]
??????? public string Name { get; set; }
??????? [DataMember]
??????? public decimal SalePrice { get; set; }
??????? // ignored
??????? public string Manufacture { get; set; }
??????? public int StockCount { get; set; }
??????? public decimal WholeSalePrice { get; set; }
??????? public DateTime NextShipmentDate { get; set; }
??? }
->Formatting
Json序列化時(shí),用可選參數(shù)Formatting.Indented生成良好的顯示格式,可讀性更好。另一方面,Formatting.None會(huì)跳過不必要的空格和換行符,讓Json的結(jié)果更小。生成的顯示格式更加緊湊,也許效率更高。
->NullValueHandling
?? 在序列化器中NullVlaueHandling是可選的。它控制序列化器如何處理值為null的屬性。通過設(shè)置NullValueHandling.Ignore值,序列化器會(huì)跳過值為null的屬性。
? public class Movie
??? {
??????? public string Name { get; set; }
??????? public string Description { get; set; }
??????? public string Classification { get; set; }
??????? public string Studio { get; set; }
??????? public DateTime? ReleaseDate { get; set; }
??????? public List<string> ReleaseCountries { get; set; }
??? }
測(cè)試1:
?????????? Movie movie = new Movie();
??????????? movie.Name = "Bad Boys III";
??????????? movie.Description = "It's no Bad Boys";
??????????? string included = JsonConvert.SerializeObject(movie,
????????????? Formatting.Indented,
????????????? new JsonSerializerSettings { });
??????????? Console.WriteLine(included);
輸出結(jié)果:
{
? "Name": "Bad Boys III",
? "Description": "It's no Bad Boys",
? "Classification": null,
? "Studio": null,
? "ReleaseDate": null,
? "ReleaseCountries": null
}
測(cè)試2:
?????????? string ignored = JsonConvert.SerializeObject(movie,
????????????? Formatting.Indented,
????????????? new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
??????????? Console.WriteLine(ignored);
輸出結(jié)果:
{
? "Name": "Bad Boys III",
? "Description": "It's no Bad Boys"
}
NullValueHandling也可以在單獨(dú)的屬性上用JsonPropertyAttribute進(jìn)行定制。使用JsonPropertyAttribute時(shí)設(shè)置的NullValueHandling值會(huì)在Json序列化器中為該屬性進(jìn)行重寫。
->DefaultValuehandling
?? 在序列化器中DefaultValuehandling是可選的。它控制序列化器如何處理帶有默認(rèn)值的屬性。通過設(shè)置DefaultValuehandling.Ignore值,序列化器會(huì)跳過帶有默認(rèn)值的屬性。對(duì)于引用類型為null,對(duì)于值類型,如int和DateTime,序列化器將跳過默認(rèn)未初使化值的值類型。
? Json.Net也允許你通過DefaultValueAttribute自定義默認(rèn)值,例如:如果一個(gè)字符串類型的屬性Department在它的默認(rèn)狀態(tài)下總是返回一個(gè)空字符,但是在你的Json對(duì)象中你不想要那個(gè)空字符串,你可以在Department上使用空字符串參數(shù)標(biāo)記DefaultValueAttribute,這意味著Department在序列化時(shí)不再寫入Json中,除非它有非空值。
? public class Invoice
??? {
??????? public string Company { get; set; }
??????? public decimal Amount { get; set; }
??????? // false is default value of bool
??????? public bool Paid { get; set; }
??????? // null is default value of nullable
??????? public DateTime? PaidDate { get; set; }
??????? // customize default values
??????? [DefaultValue(30)]
??????? public int FollowUpDays { get; set; }
??????? [DefaultValue("")]
??????? public string FollowUpEmailAddress { get; set; }
??? }
測(cè)試1:
???????????Invoice invoice = new Invoice
??????????? {
??????????????? Company = "Acme Ltd.",
??????????????? Amount = 50.0m,
??????????????? Paid = false,
??????????????? FollowUpDays = 30,
??????????????? FollowUpEmailAddress = string.Empty,
??????????????? PaidDate = null
??????????? };
??????????? string includedDefaultValue = JsonConvert.SerializeObject(invoice,
????????????? Formatting.Indented,
????????????? new JsonSerializerSettings { });
??????????? Console.WriteLine(includedDefaultValue);
輸出結(jié)果:
{
? "Company": "Acme Ltd.",
? "Amount": 50.0,
? "Paid": false,
? "PaidDate": null,
? "FollowUpDays": 30,
? "FollowUpEmailAddress": ""
}
測(cè)試2:
?????????? ?string ignoredDefaultValue = JsonConvert.SerializeObject(invoice,
????????????? Formatting.Indented,
????????????? new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore });
??????????? Console.WriteLine(ignoredDefaultValue);
輸出結(jié)果:
{
? "Company": "Acme Ltd.",
? "Amount": 50.0,
? "Paid": false//??
}
DefaultValueHandling也可以在單獨(dú)的屬性上用JsonPropertyAttribute進(jìn)行定制。使用JsonPropertyAttribute時(shí)設(shè)置的DefaultValueHandling值會(huì)在Json序列化器中為該屬性進(jìn)行重寫。
->IContractResolver
? 為了獲得更多的靈活性,IContractResolver接口提供了定制.Net對(duì)象序列化為Json的每一個(gè)方面,包括在運(yùn)行時(shí)改變序列化的行為。
?public class DynamicContractResolver : DefaultContractResolver
??? {
??????? private readonly char _startingWithChar;
??????? public DynamicContractResolver(char startingWithChar)
??????? {
??????????? _startingWithChar = startingWithChar;
??????? }
??????? protected override IList<JsonProperty> CreateProperties(JsonObjectContract contract)
??????? {
??????????? IList<JsonProperty> properties = base.CreateProperties(contract);
??????????? // only serializer properties that start with the specified character
??????????? properties =
????????????? properties.Where(p => p.PropertyName.StartsWith(_startingWithChar.ToString())).ToList();
??????????? return properties;
??????? }
??? }
??? public class Book
??? {
??????? public string BookName { get; set; }
??????? public decimal BookPrice { get; set; }
??????? public string AuthorName { get; set; }
??????? public int AuthorAge { get; set; }
??????? public string AuthorCountry { get; set; }
??? }
測(cè)試:
?????????? Book book = new Book
??????????? {
??????????????? BookName = "The Gathering Storm",
??????????????? BookPrice = 16.19m,
??????????????? AuthorName = "Brandon Sanderson",
??????????????? AuthorAge = 34,
??????????????? AuthorCountry = "United States of America"
??????????? };
??????????? string startingWithA = JsonConvert.SerializeObject(book, Formatting.Indented,
????????????? new JsonSerializerSettings { ContractResolver = new DynamicContractResolver('A') });
??????????? Console.WriteLine(startingWithA);
??????????? // {
??????????? //?? "AuthorName": "Brandon Sanderson",
??????????? //?? "AuthorAge": 34,
??????????? //?? "AuthorCountry": "United States of America"
??????????? // }
??????????? string startingWithB = JsonConvert.SerializeObject(book, Formatting.Indented,
????????????? new JsonSerializerSettings { ContractResolver = new DynamicContractResolver('B') });
??????????? Console.WriteLine(startingWithA);
??????????? // {
??????????? //?? "BookName": "The Gathering Storm",
??????????? //?? "BookPrice": 16.19
??????????? // }
IContractResolver接口提供了一種方法去定制序列化器如何去序列化和反序列化.Net對(duì)象為Json對(duì)象
實(shí)現(xiàn)IContractResolver接口,然后為Json序列化器分配一個(gè)實(shí)例對(duì)象,這樣你就可以控制對(duì)象是否被序列化為Json對(duì)象或者Json數(shù)組、對(duì)象的成員應(yīng)該被序列化成什么、如何被序列化、及他們被誰調(diào)用等。
->DefaultContractResolver
???DefaultContractResolver是序列化器默認(rèn)的解析器,它以虛函數(shù)的形式提供了很多擴(kuò)展功能,可以被覆寫(overriden).
->CamelCasePropertyNamesContractResolver
?? CamelCasePropertyNamesContractResolver繼承自DefaultContractResolver,并且簡單的覆寫了Json屬性名為camel命名規(guī)則的形式(首字母小寫)
? public class Product
??? {
??????? public string Name { get; set; }
??????? public decimal Price { get; set; }
??????? public DateTime ExpiryDate { get; set; }
??????? public string[] Sizes { get; set; }
??? }
測(cè)試:
?Product product = new Product
??????????? {
??????????????? ExpiryDate = new DateTime(2010, 12, 20, 18, 1, 0, DateTimeKind.Utc),
??????????????? Name = "Widget",
??????????????? Price = 9.99m,
??????????????? Sizes = new[] { "Small", "Medium", "Large" }
??????????? };
??????????? string json = JsonConvert.SerializeObject(
??????????????????????????? product,
??????????????????????????? Formatting.Indented,
??????????????????????????? new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }
???????????????????????????? );
??????????? Console.WriteLine(json);
輸出結(jié)果:
{
? "name": "Widget",
? "price": 9.99,
? "expiryDate": "\/Date(1292868060000)\/",
? "sizes": [
??? "Small",
??? "Medium",
??? "Large"
? ]
CustomCreationConverter是一個(gè)在序列化過程中提供自定方式去創(chuàng)建一個(gè)對(duì)象的Json轉(zhuǎn)換器,一旦對(duì)象被創(chuàng)建,它將被序列化器填充值。
?public interface IPerson
??? {
??????? string FirstName { get; set; }
??????? string LastName { get; set; }
??????? DateTime BirthDate { get; set; }
??? }
??? public class Employee : IPerson
??? {
??????? public string FirstName { get; set; }
??????? public string LastName { get; set; }
??????? public DateTime BirthDate { get; set; }
??????? public string Department { get; set; }
??????? public string JobTitle { get; set; }
??? }
??? public class PersonConverter : CustomCreationConverter<IPerson>
??? {
??????? public override IPerson Create(Type objectType)
??????? {
??????????? return new Employee();
??????? }
??? }
這是一個(gè)非常簡單的例子。更復(fù)雜的場(chǎng)景可能包含一個(gè)對(duì)象工廠或者服務(wù)定位器(service locator)用來在運(yùn)行時(shí)解析這個(gè)對(duì)象。
測(cè)試:???
????? string json = @"[
????????????? {
??????????????? ""FirstName"": ""Maurice"",
??????????????? ""LastName"": ""Moss"",
??????????????? ""BirthDate"": ""\/Date(252291661000)\/"",
??????????????? ""Department"": ""IT"",
??????????????? ""JobTitle"": ""Support""
????????????? },
????????????? {
??????????????? ""FirstName"": ""Jen"",
??????????????? ""LastName"": ""Barber"",
??????????????? ""BirthDate"": ""\/Date(258771661000)\/"",
??????????????? ""Department"": ""IT"",
??????????????? ""JobTitle"": ""Manager""
????????????? }
??????????? ]";
??????????? List<IPerson> people = JsonConvert.DeserializeObject<List<IPerson>>(json, new PersonConverter());
??????????? IPerson person = people[0];
??????????? Console.WriteLine(person.GetType());// CustomCreationConverterTest.Employee??????????
??????????? Console.WriteLine(person.FirstName);// Maurice
??????????? Employee employee = (Employee)person;
??????????? Console.WriteLine(employee.JobTitle);// Support
Json.Net支持在序列化和反序列化的過程中進(jìn)行異常處理。異常處理讓您捕獲一個(gè)異常,您可以選擇是否處理它,繼續(xù)序列化或者讓異常拋給上一層,在你的應(yīng)用程序中被拋出。
異常處理通過兩個(gè)方法來定義:the Error event on JsonSerializer 和 OnErrorAttribute
>Error Event
? error event是一個(gè)建立在JsonSerializer 上的異常處理.當(dāng)序列化或者反序列化JSON時(shí),任何有異常拋出的情況error event都會(huì)被觸發(fā).就像建立在JsonSerializer上的所有設(shè)置一樣,它也可以在JsonSerializerSettings 上進(jìn)行設(shè)置從而傳遞給JsonConvert的序列化方法.
示例:
?List<string> errors = new List<string>();
??????????? List<DateTime> c = JsonConvert.DeserializeObject<List<DateTime>>(@"[
????????????????? ""2010-12-19T00:00:00Z"",
????????????????? ""I am not a date and will error!"",
????????????????? [
??????????????????? 1
????????????????? ],
????????????????? ""2011-01-01T00:00:00Z"",
????????????????? null,
????????????????? ""2010-12-25T00:00:00Z""
????????????????? ]", new JsonSerializerSettings()
??????????????????????? {
??????????????????????????? Error = delegate(object sender, Newtonsoft.Json.Serialization.ErrorEventArgs e)
??????????????????????????? {
??????????????????????????????? errors.Add(e.ErrorContext.Error.Message);
??????????????????????????????? e.ErrorContext.Handled = true;
??????????????????????????? },
??????????????????????????? Converters = { new IsoDateTimeConverter() }
??????????????????????? });
??????????? foreach (DateTime t in c)
??????????? {
??????????????? Console.WriteLine(t.ToString());
??????????? }
??????????? //2010-12-19 00:00:00
??????????? //2011-01-01 00:00:00
??????????? //2010-12-25 00:00:00
??????????? foreach (string err in errors)
??????????? {
??????????????? Console.WriteLine(err);
??????????? }
??????????? //The string was not recognized as a valid DateTime. There is a unknown word starting at index 0.
??????????? //Unexpected token parsing date. Expected String, got StartArray.
??????????? //Cannot convert null value to System.DateTime.
? 在這個(gè)例子中我們把一個(gè)Json數(shù)組反序列化為一個(gè)DateTime的集合,在JsonSerializerSettings中有一個(gè)hander被賦值成了error event ,它用來記錄error message,并標(biāo)記這個(gè)error為已處理(handled).
反序列化JSON的結(jié)果是三個(gè)被成功反序列化的日期和三個(gè)error messages:一個(gè)是不正確的格式,"I am not a date and will error!",一個(gè)是嵌套了JSON數(shù)組,最后一個(gè)是null值,因?yàn)槎x的list不允許有可空類型的DateTime.這個(gè)事件處理已經(jīng)記錄了這些信息,Json.Net在序列化時(shí)繼續(xù)進(jìn)行(沒有因?yàn)楫惓6V?,因?yàn)檫@些錯(cuò)誤已經(jīng)被標(biāo)記為已處理。
?? 值得注意的是,在Json.Net進(jìn)行異常處理時(shí),沒有處理的異常將會(huì)被拋到上一層,并在它的每個(gè)parent觸發(fā)事件,例如:在序列化若干對(duì)象的集合時(shí),一個(gè)未處理的異常將被觸發(fā)兩次,首先在對(duì)象上,然后在集合上。這樣就會(huì)讓您在處理異常的時(shí)候,選擇在它發(fā)生的地方,或者是它的一個(gè)parent上。
?JsonSerializer serializer = new JsonSerializer();
??????????? serializer.Error += delegate(object sender, Newtonsoft.Json.Serialization.ErrorEventArgs e)
??????????? {
??????????????? // only log an error once
??????????????? if (e.CurrentObject == e.ErrorContext.OriginalObject)
??????????????????? errors.Add(e.ErrorContext.Error.Message);
??????????? };
如果您不是立即處理一個(gè)異常,僅僅是想針對(duì)它完成一次操作,您可以驗(yàn)證一下ErrorEventArg's CurrentObject是否等于OriginalObject.OriginalObject是拋出異常的對(duì)象,CurrentObject是事件被觸發(fā)的對(duì)象.他們只會(huì)在第一次(事件被OriginalObject觸發(fā)時(shí))相等.
>OnErrorAttribute
?OnErrorAttribute的工作方式非常像其他Json.Net支持的.NET serialization attributes ,簡單地把它標(biāo)記在帶有正確參數(shù)(一個(gè)StreamingContext和一個(gè)ErrorContext)的方法上就可以使用了,與方法的名字沒有關(guān)系。
示例:
? public class PersonError
??? {
??????? private List<string> _roles;
??????? public string Name { get; set; }
??????? public int Age { get; set; }
??????? public List<string> Roles
??????? {
??????????? get
??????????? {
??????????????? if (_roles == null)
??????????????????? throw new Exception("Roles not loaded!");
??????????????? return _roles;
??????????? }
??????????? set { _roles = value; }
??????? }
??????? public string Title { get; set; }
??????? [OnError]
??????? internal void OnError(StreamingContext context, ErrorContext errorContext)
??????? {
??????????? errorContext.Handled = true;
??????? }
??? }
在這個(gè)例子中,當(dāng)_roles沒有被設(shè)置值時(shí)訪問Roles屬性將會(huì)拋出一個(gè)異常.在序列化Roles屬性時(shí),異常處理的方法將設(shè)置error為handled,從而允許Json.Net繼續(xù)序列化這個(gè)類。
測(cè)試:
?PersonError person = new PersonError
??????????? {
??????????????? Name = "George Michael Bluth",
??????????????? Age = 16,
??????????????? Roles = null,
??????????????? Title = "Mister Manager"
??????????? };
??????????? string json = JsonConvert.SerializeObject(person, Formatting.Indented);
??????????? Console.WriteLine(json);
輸出:
??????????? {
????????????? "Name": "George Michael Bluth",
????????????? "Age": 16,
????????????? "Title": "Mister Manager"
??????????? }
?
posted @ 2011-06-11 15:10 資源收集 閱讀(57) 評(píng)論(0)?編輯 Json.Net學(xué)習(xí)筆記(十) 保持對(duì)象引用默認(rèn)情況下,Json.Net將通過對(duì)象的值來序列化它遇到的所有對(duì)象。如果工個(gè)list包含兩個(gè)Person引用,這兩個(gè)引用都指向同一個(gè)對(duì)象,Json序列化器將輸出每一個(gè)引用的所有名稱和值。
定義類:
? public class Person
??? {
??????? public DateTime BirthDate { get; set; }
??????? public DateTime LastModified { get; set; }
??????? public string Name { get; set; }
??? }
測(cè)試:
???????? Person p = new Person()
??????????? {
??????????????? BirthDate = new DateTime(1985, 11, 27, 0, 0, 0, DateTimeKind.Utc),
??????????????? LastModified = new DateTime(2010, 12, 20, 0, 0, 0, DateTimeKind.Utc),
??????????????? Name = "James"
??????????? };
??????????? List<Person> people = new List<Person>();
??????????? people.Add(p);
??????????? people.Add(p);
??????????? string json = JsonConvert.SerializeObject(people, Formatting.Indented);
??????????? Console.WriteLine(json);
輸出結(jié)果:
[
? {
??? "BirthDate": "\/Date(501897600000)\/",
??? "LastModified": "\/Date(1292803200000)\/",
??? "Name": "James"
? },
? {
??? "BirthDate": "\/Date(501897600000)\/",
??? "LastModified": "\/Date(1292803200000)\/",
??? "Name": "James"
? }
]
在大多數(shù)情況下這是期望的結(jié)果,但是在某些場(chǎng)景下,將list中的第二項(xiàng)作為第一項(xiàng)的一個(gè)引用來輸出會(huì)是一個(gè)更好的解決方案。如果上面的Json現(xiàn)在被反序列化,返回的list會(huì)包含兩個(gè)完全分離的對(duì)象,它們具有相同的值。通過值來輸出引用也會(huì)在對(duì)象上導(dǎo)致循環(huán)引用的發(fā)生。
>PreserveReferencesHandling
?? string json2 = JsonConvert.SerializeObject(people, Formatting.Indented,
??????????????? new JsonSerializerSettings() { PreserveReferencesHandling = PreserveReferencesHandling.Objects });
??????????? Console.WriteLine(json2);
輸出結(jié)果:
???????? ?[
????????????? {
??????????????? "$id": "1",
??????????????? "BirthDate": "\/Date(501897600000)\/",
??????????????? "LastModified": "\/Date(1292803200000)\/",
??????????????? "Name": "James"
????????????? },
????????????? {
??????????????? "$ref": "1"
????????????? }
??????????? ]?
????????? List<Person> deserializedPeople = JsonConvert.DeserializeObject<List<Person>>(json2,
??????????????? new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects });
??????????? Console.WriteLine(deserializedPeople.Count);// 2???????
??????????? Person p1 = deserializedPeople[0];
??????????? Person p2 = deserializedPeople[1];
??????????? Console.WriteLine(p1.Name);// James
??????????? Console.WriteLine(p2.Name);// James
??????????? bool equal = Object.ReferenceEquals(p1, p2);// true
在list中的第一個(gè)Person被序列化時(shí)增加了一個(gè)額外的對(duì)象Id,現(xiàn)在第二個(gè)Person對(duì)象僅僅是第一個(gè)的引用。
現(xiàn)在使用PreserveReferencesHandling后,在序列化時(shí)只創(chuàng)建了一個(gè)Person對(duì)象,list中包含它的兩個(gè)引用,原來我們叫作反射(mirroring) 。
>IsReference on JsonObjectAttribute, JsonArrayAttribute and JsonPropertyAttribute
? 在對(duì)象序列化器上設(shè)置PreserveReferencesHandling,將會(huì)改變所有對(duì)象被序列化和反序列化的方式。為了更加細(xì)致地控制對(duì)象和成員被序列化為一個(gè)引用,可以在JsonObjectAttribute, JsonArrayAttribute 和 JsonPropertyAttribute上使用IsReference 屬性.
在JsonObjectAttribute, JsonArrayAttribute 上設(shè)置IsReference 為true,意味著Json序列化器總是會(huì)序列這個(gè)類型為一個(gè)引用。在JsonPropertyAttribute上設(shè)置IsReference為true將只序列化這個(gè)屬性為一個(gè)引用。
?[JsonObject(IsReference = true)]
??? public class EmployeeReference
??? {
??????? public string Name { get; set; }
??????? public EmployeeReference Manager { get; set; }
??? }
測(cè)試:
?????????? List<EmployeeReference> empList = new List<EmployeeReference>();
??????????? empList.Add(empRef);
??????????? empList.Add(empRef);
??????????? string empRefJson = JsonConvert.SerializeObject(empList, Formatting.Indented);
??????????? Console.WriteLine(empRefJson);
輸出結(jié)果:
[
? {
??? "$id": "1",
??? "Name": "IsReference",
??? "Manager": null
? },
? {
??? "$ref": "1"
? }
]
>IReferenceResolver
要想定制引用的生成方式,可以繼承自IReferenceResolver接口來使用Json序列化器。
posted @ 2011-06-11 15:10 資源收集 閱讀(49) 評(píng)論(0)?編輯 Json.Net學(xué)習(xí)筆記(七) 序列化集合Json序列化器為序列化及反序列化集合對(duì)象提供了良好的支持.
->Serializing
?? 為了序列化一個(gè)集合---一個(gè)泛型的list,array,dictionary,或者自定義集合---簡單地調(diào)用序列化器,使用您想要進(jìn)行序列化的集合對(duì)象作為參數(shù),Json.Net會(huì)序列化集合以及所有它包含的值。
示例:
public class Product
??? {
??????? public string Name { get; set; }
??????? public decimal Price { get; set; }
??????? [JsonConverter(typeof(IsoDateTimeConverter))]
??????? public DateTime ExpiryDate { get; set; }
??? }
測(cè)試:
??????????? Product p1 = new Product()
??????????? {
??????????????? Name = "Product 1",
??????????????? Price = 99.95m,
??????????????? ExpiryDate = new DateTime(2010, 12, 19, 0, 0, 0, DateTimeKind.Utc)
??????????? };
??????????? Product p2 = new Product
??????????? {
??????????????? Name = "Product 2",
??????????????? Price = 12.50m,
??????????????? ExpiryDate = new DateTime(2011, 1, 1, 0, 0, 0, DateTimeKind.Utc)
??????????? };
??????????? List<Product> products = new List<Product>();
??????????? products.Add(p1);
??????????? products.Add(p2);
??????????? string json = JsonConvert.SerializeObject(products, Formatting.Indented);
??????????? Console.WriteLine(json);
輸出結(jié)果:
[
? {
??? "Name": "Product 1",
??? "Price": 99.95,
??? "ExpiryDate": "2010-12-19T00:00:00Z"
? },
? {
??? "Name": "Product 2",
??? "Price": 12.50,
??? "ExpiryDate": "2011-01-01T00:00:00Z"
? }
]
->Deserializing
? 為了反序列化Json到一個(gè).Net集合中,只要指定一個(gè)您想要反序列化的集合類型就可以了,Json.Net支持多種類型的集合.
示例:
? ? string json2 = @"[
????????????????????????????? {
??????????????????????????????? ""Name"": ""Product 1"",
??????????????????????????????? ""ExpiryDate"": ""2010-12-19T00:00:00Z"",
??????????????????????????????? ""Price"": 99.95,
??????????????????????????????? ""Sizes"": null
????????????????????????????? },
????????????????????????????? {
??????????????????????????????? ""Name"": ""Product 2"",
??????????????????????????????? ""ExpiryDate"": ""2011-01-01T00:00:00Z"",
??????????????????????????????? ""Price"": 12.50,
??????????????????????????????? ""Sizes"": null
????????????????????????????? }
??????????????????????????? ]";
??????????? List<Product> productList = JsonConvert.DeserializeObject<List<Product>>(json2);
??????????? Console.WriteLine(productList.Count);//2
??????????? Product product1 = productList[0];
??????????? Console.WriteLine(product1.Name);//Product 1
->Deserializing Dictionaries
? 使用Json.Net你也可以反序列化一個(gè)Json對(duì)象到一個(gè).Net的泛型Dictionary中.Json對(duì)象的屬性名和屬性值將會(huì)被添加到Dictionary中.
示例:
? ? ? ? ? ? string jsonDictionary = @"{""key1"":""value1"",""key2"":""value2""}";
??????????? Dictionary<string, string> dic = JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonDictionary);
??????????? Console.WriteLine(dic.Count);//2
??????????? Console.WriteLine(dic["key1"]);//value1
Json.Net支持序列化回調(diào)方法,回調(diào)方法通過Json序列化器(JsonSerializer)可以用來操作一個(gè)對(duì)象,在它被序列化和反序列化之前或者之后.
OnSerializing?
OnSerialized?
OnDeserializing?
OnDeserialized
為了告訴序列化器在對(duì)象的序列化生命周期中哪個(gè)方法應(yīng)該被調(diào)用,需要用適當(dāng)?shù)腶ttribute(OnSerializingAttribute,?OnSerializedAttribute,?OnDeserializingAttribute,?OnDeserializedAttribute)來標(biāo)記方法.
例如對(duì)象序列化的回調(diào)方法:
using Newtonsoft.Json;
using System.Runtime.Serialization;
?public class SerializationEventTestObject
??? {
??????? // This member is serialized and deserialized with no change.
??????? public int Member1 { get; set; }
??????? // The value of this field is set and reset during and?
??????? // after serialization.
??????? public string Member2 { get; set; }
??????? // This field is not serialized. The OnDeserializedAttribute?
??????? // is used to set the member value after serialization.
??????? [JsonIgnore]
??????? public string Member3 { get; set; }
??????? // This field is set to null, but populated after deserialization.
??????? public string Member4 { get; set; }
??????? public SerializationEventTestObject()
??????? {
??????????? Member1 = 11;
??????????? Member2 = "Hello World!";
??????????? Member3 = "This is a nonserialized value";
??????????? Member4 = null;
??????? }
??????? [OnSerializing]
??????? internal void OnSerializingMethod(StreamingContext context)
??????? {
??????????? Member2 = "This value went into the data file during serialization.";
??????? }
??????? [OnSerialized]
??????? internal void OnSerializedMethod(StreamingContext context)
??????? {
??????????? Member2 = "This value was reset after serialization.";
??????? }
??????? [OnDeserializing]
??????? internal void OnDeserializingMethod(StreamingContext context)
??????? {
??????????? Member3 = "This value was set during deserialization";
??????? }
??????? [OnDeserialized]
??????? internal void OnDeserializedMethod(StreamingContext context)
??????? {
??????????? Member4 = "This value was set after deserialization.";
??????? }
??? }
示例對(duì)象被序列化和反序列化:
?SerializationEventTestObject obj = new SerializationEventTestObject();
??????????? Console.WriteLine(obj.Member1);// 11
??????????? Console.WriteLine(obj.Member2);// Hello World!
??????????? Console.WriteLine(obj.Member3);// This is a nonserialized value
??????????? Console.WriteLine(obj.Member4);// null
??????????? string json = JsonConvert.SerializeObject(obj, Formatting.Indented);
??????????? Console.WriteLine(json);
??????????? //? "Member1": 11,
??????????? //? "Member2": "This value went into the data file during serialization.",
??????????? //? "Member4": null
??????????? //}
?
??????????? Console.WriteLine(obj.Member1);//11
??????????? Console.WriteLine(obj.Member2);// This value was reset after serialization.
??????????? Console.WriteLine(obj.Member3);// This is a nonserialized value
??????????? Console.WriteLine(obj.Member4);// null
??????????? obj = JsonConvert.DeserializeObject<SerializationEventTestObject>(json);
??????????? Console.WriteLine(obj.Member1);//11
??????????? Console.WriteLine(obj.Member2);// This value went into the data file during serialization.
??????????? Console.WriteLine(obj.Member3);// This value was set during deserialization
??????????? Console.WriteLine(obj.Member4);// This value was set after deserialization.
Attributes 可以用來控制Json.Net如何序列化和反序列化.Net對(duì)象。
>JsonObjectAttribute--標(biāo)記在類上,用于控制該類如何被序列化為一個(gè)Json對(duì)象(JSON Object)
>JsonArrayAttribute--標(biāo)記在集合上,用于控制該集合如何被序列化為一個(gè)Json集合(JSON Array)
>JsonPropertyAttribute--標(biāo)記在字段和屬性上,用于控制它如何被序列化為一個(gè)Json對(duì)象中的屬性
>JsonConverterAttribute--標(biāo)記在類或者字段和屬性上,用于序列化時(shí)指定Json轉(zhuǎn)換器(JsonConverter)
?和使用內(nèi)置的Json.Net attributes一樣,當(dāng)確定Json如何被序列化和反序列化時(shí),Json.Net也查找DataContract和DataMember attributes。如果都存在,Json.Net 序列化特性將優(yōu)先使用。
示例:
?? [JsonObject(MemberSerialization.OptOut)]
??? public class Person
??? {
??????? // "John Smith"
??????? [JsonProperty]
??????? public string Name { get; set; }
??????? // "2000-12-15T22:11:03"
??????? [JsonProperty]
??????? [JsonConverter(typeof(IsoDateTimeConverter))]
??????? public DateTime BirthDate { get; set; }
??????? // new Date(976918263055)
??????? [JsonProperty]
??????? [JsonConverter(typeof(JavaScriptDateTimeConverter))]
??????? public DateTime LastModified { get; set; }
??????? // not serialized
??????? public string Department { get; set; }
??? }
->JsonObjectAttribute
??這里的MemberSerialization標(biāo)記指定成員序列化為opt-in(每一個(gè)成員都必須標(biāo)記JsonProperty或者DataMember attribute才被序列化)或者opt-out(默認(rèn)情況下,除了被標(biāo)記為JsonIgnoreAttribute的所有成員都將被序列化,這是Json.Net 的默認(rèn)行為)
? Json.Net把實(shí)現(xiàn)了IEnumerable接口的.Net類序列化為一個(gè)Json集合,用IEnumerable 的值來填充該集合。標(biāo)記JsonPropertyAttribute來重寫此行為,并強(qiáng)制序列化器序列化該類的字段和屬性。
->JsonPropertyAttribute
? JsonPropertyAttribute有很多用途
??? 1.默認(rèn)情況下,Json 屬性與.Net屬性有相同的名字,這個(gè)attribute允許自定義屬性名
??? 2.當(dāng)member serialization 被設(shè)置成opt-in時(shí),指定屬性應(yīng)該被序列化
??? 3.在序列化和反序列化時(shí)包含非public屬性
->JsonIgnoreAttribute
? 從序列化中排除指定的字段或者屬性
->JsonConverterAttribute
? JsonConverterAttribute指定Json序列化器(JsonSerializer)用來轉(zhuǎn)換一個(gè)對(duì)象
? 這個(gè)特性可以用來標(biāo)記類或者成員,當(dāng)它用來標(biāo)記類的時(shí)候,由attribute指定的JsonConverter將為類提供默認(rèn)的序列化方法.當(dāng)它用來標(biāo)記字段或者屬性的時(shí)候,指定的JsonConverter將一直用于序列化該值。
? 使用JsonConverter的優(yōu)先級(jí)順序?yàn)?#xff1a;先成員,后類,最后為傳給JsonSerializer的任何轉(zhuǎn)換器.
示例:
??? public class MemberConverterClass
??? {
??????? public DateTime DefaultConverter { get; set; }
??????? [JsonConverter(typeof(IsoDateTimeConverter))]
??????? public DateTime MemberConverter { get; set; }
??? }//注:這是一個(gè)JsonConverterAttribute 應(yīng)用于屬性的例子
測(cè)試:
?DateTime date = Convert.ToDateTime("1970-01-01T00:00:00Z").ToUniversalTime();
??????????? MemberConverterClass c = new MemberConverterClass
??????????? {
??????????????? DefaultConverter = date,
??????????????? MemberConverter = date
??????????? };
??????????? string json = JsonConvert.SerializeObject(c, Formatting.Indented);
??????????? Console.WriteLine(json);
輸出結(jié)果:
{
? "DefaultConverter": "\/Date(0)\/",
? "MemberConverter": "1970-01-01T00:00:00Z"
} posted @ 2011-06-11 15:08 資源收集 閱讀(133) 評(píng)論(0)?編輯 Json.Net學(xué)習(xí)筆記(六) Json.Net中關(guān)于時(shí)間的序列化
DateTime類型在Json中表示是很難的。
問題來源于JSON spec?(Json規(guī)范)自身,沒有精確的語法。這個(gè)規(guī)范包括objects, arrays, strings, integers 和 floats,但是對(duì)于date是什么樣子的沒有定義準(zhǔn)確的標(biāo)準(zhǔn)。
關(guān)于時(shí)間,Json.Net使用的默認(rèn)格式與微軟:"\/Date(1198908717056)\/"相同,您可以從此外獲得更多信息.
DateTime JsonConverters
由于在Json中沒有關(guān)于時(shí)間的準(zhǔn)確標(biāo)準(zhǔn),當(dāng)與其他系統(tǒng)進(jìn)行互操作時(shí)就會(huì)有大量不同的時(shí)間格式。幸運(yùn)的是,Json.Net為了處理讀寫自定義時(shí)間提供了一個(gè)解決方案:JsonConverters. JsonConverter是用來重寫一個(gè)類型如何被序列化的。
示例:?
public class LogEntry
??? {
??????? public string Details { get; set; }
??????? public DateTime LogDate { get; set; }
??? }
測(cè)試1:
?????? LogEntry logEntry = new LogEntry()
??????????? {
??????????????? LogDate = new DateTime(2010, 12, 19, 0, 0, 0, DateTimeKind.Utc),
??????????????? Details = "Application started."
??????????? };
??????????? string defaultJson = JsonConvert.SerializeObject(logEntry, Formatting.Indented);
??????????? Console.WriteLine(defaultJson);
輸出結(jié)果:
{
? "Details": "Application started.",
? "LogDate": "\/Date(1292716800000)\/"
}
測(cè)試2:
??? string javascriptJson = JsonConvert.SerializeObject(logEntry, Formatting.Indented, new JavaScriptDateTimeConverter());
???? Console.WriteLine(javascriptJson);
輸出結(jié)果:
{
? "Details": "Application started.",
? "LogDate": new Date(
??? 1292716800000
? )
}
測(cè)試3:
??????????? string isoJson = JsonConvert.SerializeObject(logEntry, Formatting.Indented, new IsoDateTimeConverter());
??????????? Console.WriteLine(isoJson);
輸出結(jié)果:
{
? "Details": "Application started.",
? "LogDate": "2010-12-19T00:00:00Z"
}
?簡單地,通過JsonConverter您可以使用Json.Net的序列化器
>JavaScriptDateTimeConverter
? JavaScriptDateTimeConverter類是來自于Json.Net的兩個(gè)DataTime Json轉(zhuǎn)換器之一,這個(gè)轉(zhuǎn)換器序列化一個(gè)DateTime類型為一個(gè)JavaScipt日期對(duì)象(https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Date)
? new Date(1292716800000)
從技術(shù)上講,根據(jù)規(guī)范這是無效的數(shù)據(jù)格式,但是所有的瀏覽器、和一些Json的框架包括Json.Net都支持它。
>IsoDateTimeConverter
? IsoDateTimeConverter序列一個(gè)DateTime類型為一個(gè)ISO 8601格式的字符串.
? "2010-12-19T00:00:00Z"
IsoDateTimeConverter 類有一個(gè)屬性DateTimeFormat,用來更進(jìn)一步的自定義字符串格式.
最后要注意的一件事是,所有被Json.Net返回的日期值都是UTC Time
posted @ 2011-06-11 15:08 資源收集 閱讀(109) 評(píng)論(0)?編輯 Json.Net學(xué)習(xí)筆記(三) Json與Xml之間的轉(zhuǎn)換Json.Net 支持 Json 與Xml之間的相互轉(zhuǎn)換.
轉(zhuǎn)換規(guī)則:
?1.元素保持不變
?2.屬性添加前綴@
?3.單個(gè)子文本結(jié)點(diǎn)直接作為元素結(jié)點(diǎn)的值,否則通過#text訪問
?4.XML聲明和處理指令以?為前綴
?5.字符數(shù)據(jù)(Character data)、注釋、whitespace 和significate whitespace結(jié)點(diǎn)分別通過#cdata-section,#comment,#whitespace and #significate-whitespace 訪問。
?6.同一級(jí)多個(gè)相同名字的結(jié)點(diǎn)作為一組,放到同一個(gè)集合中
?7.空元素為null
using Newtonsoft.Json;
測(cè)試:
string xml = <?xml version=""1.0"" standalone=""no""?>
??????????????????????????? <root>
??????????????????????????? <person id=""1"">
??????????????????????????? <name>Alan</name>
??????????????????????????? <url>http://www.google.com</url>
??????????????????????????? </person>
??????????????????????????? <person id=""2"">
??????????????????????????? <name>Louis</name>
??????????????????????????? <url>http://www.yahoo.com</url>
??????????????????????????? </person>
??????????????????????????? Hello World
??????????????????????????? </root>";
??????????? XmlDocument doc = new XmlDocument();
??????????? doc.LoadXml(xml);
?????????? //XML?to JSON
??????????? string jsonText = JsonConvert.SerializeXmlNode(doc, Newtonsoft.Json.Formatting.Indented);
??????????? Console.WriteLine(jsonText);
輸出結(jié)果:
{
? "?xml": {
??? "@version": "1.0",
??? "@standalone": "no"
? },
? "root": {
??? "person": [
????? {
??????? "@id": "1",
??????? "name": "Alan",
??????? "url": "http://www.google.com"
????? },
????? {
??????? "@id": "2",
??????? "name": "Louis",
??????? "url": "http://www.yahoo.com"
????? }
??? ],
??? "#text": "\r\n??????????????????????????? Hello World\r\n??????????????????????????? "
? }
}
?
??????????? //JSON to XML
?????????? ?XmlDocument docJson = (XmlDocument)JsonConvert.DeserializeXmlNode(jsonText);
??????????? Console.WriteLine(docJson.InnerXml);
為了手動(dòng)讀寫Json對(duì)象,Json.Net提供了JsonReader 和 JsonWriter這兩個(gè)抽象類及其相應(yīng)的派生類:
1.JsonTextReader 和 JsonTextWriter
用來讀寫Json對(duì)象的文本,JsonTextWriter 有大量設(shè)置去控制Json對(duì)象的格式。
測(cè)試:
??????????? //寫操作
??????????? StringBuilder sb = new StringBuilder();
??????????? StringWriter sw = new StringWriter(sb);
??????????? using (JsonWriter jsonWriter = new JsonTextWriter(sw))
??????????? {???????????????
??????????????? jsonWriter.Formatting = Formatting.Indented;
??????????????? jsonWriter.WriteStartObject();
????????????????
??????????????? jsonWriter.WritePropertyName("CPU");
??????????????? jsonWriter.WriteValue("Intel");
??????????????? jsonWriter.WritePropertyName("PSU");
??????????????? jsonWriter.WriteValue("500W");
??????????????? jsonWriter.WritePropertyName("Drives");
??????????????? jsonWriter.WriteStartArray();
??????????????? jsonWriter.WriteValue("DVD read/writer");
??????????????? jsonWriter.WriteComment("(broken)");
??????????????? jsonWriter.WriteValue("500 gigabyte hard drive");
??????????????? jsonWriter.WriteValue("200 gigabype hard drive");
??????????????? jsonWriter.WriteEndArray();
??????????????? jsonWriter.WriteEndObject();
??????????? }
??????????? Console.WriteLine(sb.ToString());
輸出結(jié)果:
{
? "CPU": "Intel",
? "PSU": "500W",
? "Drives": [
??? "DVD read/writer"
??? /*(broken)*/,
??? "500 gigabyte hard drive",
??? "200 gigabype hard drive"
? ]
}
????? //讀操作
???? TextReader txtReader = new StringReader(sb.ToString());
??????????? using (JsonReader jsonReader = new JsonTextReader(txtReader))
??????????? {
??????????????? string readResult = "{\n";
??????????????? while (jsonReader.Read())
??????????????? {
??????????????????? if (jsonReader.TokenType == JsonToken.PropertyName)
??????????????????? {
??????????????????????? readResult += (string)jsonReader.Value + ":";
??????????????????? }
??????????????????? else if (jsonReader.TokenType == JsonToken.String)
??????????????????? {
??????????????????????? readResult += (string)jsonReader.Value + "\n";
??????????????????? }
??????????????????? else if (jsonReader.TokenType == JsonToken.StartArray)
??????????????????? {
??????????????????????? readResult += "[\n";
??????????????????????? while (jsonReader.Read())
??????????????????????? {
??????????????????????????? if (jsonReader.TokenType == JsonToken.EndArray)
??????????????????????????? {
??????????????????????????????? readResult = readResult.Remove(readResult.Length - 2, 1);
??????????????????????????????? readResult += "]\n";
??????????????????????????????? break;
??????????????????????????? }
??????????????????????????? if (jsonReader.TokenType == JsonToken.String)
??????????????????????????????? readResult += (string)jsonReader.Value + ",\n";
??????????????????????????? else if (jsonReader.TokenType == JsonToken.Comment)
??????????????????????????????? readResult += "/*" + (string)jsonReader.Value + "*/,\n";
??????????????????????? }
??????????????????? }
??????????????? }
??????????????? readResult += "}\n";
??????????????? Console.WriteLine(readResult);
???????????? }
2.JTokenReader and JTokenWriter
JTokenReader and JTokenWriter是讀寫Linq to Json對(duì)象的,他們存在于Newtonsoft.Json.Linq名字空間中
???????? JObject o = new JObject(
??????????????????????? new JProperty("Name", "ZhangSan"),
??????????????????????? new JProperty("BirthDay", new DateTime(1985, 11, 27)));
??????????? JsonSerializer serializer = new JsonSerializer();
??????????? Person person = (Person)serializer.Deserialize(new JTokenReader(o), typeof(Person));
??????????? Console.WriteLine(person.Name);//輸出ZhangSan
using Newtonsoft.Json.Linq;
定義類:
??? public class Product
??? {
??????? public string Name { get; set; }
??????? public DateTime Expiry { get; set; }
??????? public decimal Price { get; set; }
??????? public string[] Sizes { get; set; }
??? }
測(cè)試:
??????????? Product product = new Product
??????????? {
??????????????? Name = "Apple",
??????????????? Expiry = new DateTime(2010, 12, 18),
??????????????? Price = 3.99M,
??????????????? Sizes = new string[] { "Small", "Medium", "Large" }
??????????? };
??????????? string serializedJson = JsonConvert.SerializeObject(product);
????????????JObject o = JObject.Parse(serializedJson);
??????????? string name = (string)o["Name"];
??????????? //Apple
??????????? JArray sizes = (JArray)o["Sizes"];
??????????? string smallest = (string)sizes[0];
??????????? Response.Write(name + "," + smallest + "<br/>");//輸出Small
??????????? //SelectToken
??????????? smallest = (string)o.SelectToken("Sizes[0]");
??????????? Response.Write(smallest + "<br/>");//輸出Small
??????????? //SelectToken with Linq
??????????? var sizeLen5 = o["Sizes"].Select(i => (string)i).Where(i => i.Length == 5).ToList<string>();
????????? ?foreach (var size in sizeLen5)
??????????? {
??????????????? Response.Write((string)size+ " <br/>");
??????????? };//輸出Small和Large
注:JArray表示一個(gè)Json集合,JObject表示一個(gè)Json對(duì)象。
posted @ 2011-06-11 15:03 資源收集 閱讀(117) 評(píng)論(0)?編輯 Json.Net?學(xué)習(xí)筆記(一)使用Newtonsoft.Json這是一個(gè)開源的Json.Net庫。
下載地址:http://json.codeplex.com/releases/view/50552。當(dāng)前版本為 Release 8
從下載到的源代碼中獲取Newtonsoft.Json.Net20.dll,添加到自己的工程中。
using Newtonsoft.Json;
定義類:
?public class Message
??? {
??????? public string Address { get; set; }
??????? [JsonProperty(TypeNameHandling = TypeNameHandling.All)]
??????? public object Body { get; set; }
??? }
??? public class SearchDetails
??? {
??????? public string Query { get; set; }
??????? public string Language { get; set; }
??? }
測(cè)試:
?????????? Message message = new Message
??????????? {
??????????????? Address = "http://google.com",
??????????????? Body = new SearchDetails { Query = "Json.Net", Language = "en-us" }
??????????? };
??????????? string jsonMsg = JsonConvert.SerializeObject(message, Formatting.Indented);//Indented表示以縮進(jìn)形式顯示結(jié)果
??????????? System.Diagnostics.Debug.Write(jsonMsg);
??????????? Message deserialized = JsonConvert.DeserializeObject<Message>(jsonMsg);
??????????? SearchDetails searchDetails = (SearchDetails)deserialized.Body;
??????????? Response.Write(searchDetails.Query + "," + searchDetails.Language + "<br/>");
Debug輸出結(jié)果格式:
{
? "Address": "http://google.com",
? "Body": {
??? "$type": "TestJsonSerialization.SearchDetails, TestJsonSerialization",
??? "Query": "Json.Net",
??? "Language": "en-us"
? }
}
注:1.JsonProperty標(biāo)記字段或?qū)傩?#xff0c;用來控制它作為一個(gè)Json對(duì)象的屬性序列化。
?????? 2.TypeNameHandling 用來為Json序列化指定類型名。它有幾個(gè)枚舉值:
| Member | Description |
|---|---|
| None | Do not include the .NET type name when serializing types.? |
| Objects | Include the .NET type name when serializing into a JSON object structure.? |
| Arrays | Include the .NET type name when serializing into a JSON array structure.? |
| Auto | Include the .NET type name when the type of the object being serialized is not the same as its declared type.? |
| All | Always include the .NET type name when serializing.? |
| 上一篇?在ASP.NET MVC 中獲取當(dāng)前URL、controller、action(轉(zhuǎn)載) | 下一篇?ASP.NET-關(guān)于Container dataitem 與 eval方法介紹(轉(zhuǎn)帖) |
轉(zhuǎn)載于:https://www.cnblogs.com/wuyifu/p/3299784.html
總結(jié)
以上是生活随笔為你收集整理的Json.Net学习笔记的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vmware克隆centos修改linu
- 下一篇: PHP5.3.8连接Sql Server