윈도우 앱개발을 향하여

블로그 이미지
윈도우 10 스토어에 앱을 개발해 올리는 것을 목표로 하고 있습니다. 비전공자가 독학으로 시도하는 일이어서 얼마나 걸릴지 모르겠지만... 아무튼 목표는 그렇습니다!!
by 코딩하는 경제학도
  • Total hit
  • Today hit
  • Yesterday hit

Copyright

이 모든 내용은 Pluralsight에 Xavier Morera가 올린 'Getting Started with JSON in C# Using Json.NET'라는 강의의 다섯번째 챕터를 듣고 정리한 것입니다(https://app.pluralsight.com/library/courses/json-csharp-jsondotnet-getting-started/table-of-contents).


Content

Serialization Fundamentals

Settings & Attributes

Custom Serialization

Performance Tips

LINQ to JSON

JSON & XML

Binary JSON (BSON)

Json.NET Schema


Outline

Manual Serialization/Deserialization

Fragments

Populate Objects

Merge Array Handling

Attributes

Memory Usage



Serializing and deserializing manually

Json.NET is extremely fast but it relies on reflection so if speed is key, serialize/deserialize manually using JsonTextReader/Writer. (Avoids using Reflection, Less memory usage, Fastest way of reading and writing JSON)


Writing

var builder = new StringBuilder(); //Never to use strings(immutable) if you're going to be changing them too much

StringWriter writer = new StringWriter(builder);

using (var jsonWriter = new JsonWriter(writer))

{

jsonWriter.Formatting = Formatting.Indented;

jsonWriter.WriteStartArray();

for (int i =0; i < numberOfView; i++)

{

jsonWriter.WriteStartObject();

....

jsonWriter.WriteEndObject();

}

jsonWriter.WriteEndArray();

}


Reading

var reader = new JsonTextReader(new StringReader()jsonStrings);

while(reader.Read())

{

if(reader.Value != null)

{

if(reader.TokenType == JsonToken.String....)

}

}



JSON Fragments (Deserialize only what you need!)

Large JSON documents or objects may take a lot of time serializing and deserializing. However, in certain scenarios you may have a very big JSON object, but you're only interested in a specific subsection of your data. With Json.NET it is possible to extract and work with a fragment of a JSON object using Linq.


Json.NET has the capability of extracting a subsection of a big JSON text, allowing you to deserialize only that small section. This is very beneficial both in terms of performance and simplicity because you're not deserializing the entire object, that's the first one, and second, it makes the code much more readable.


List<UserInteraction> userLogs = GetTestData(); //Generate huge data

string bigLog = JsonConvert.SerializeObject(userLogs);


JArray logs = JArray.Parse(bigLog); //bigLog is huge json string

List<CourseView> courses = new List<CourseView>(); //CourseView is an objects which we are interest in bigLog 

foreach (JObject logEntry in logs)

{

courses.Add(logEntry["courseView"].ToObject<CourseView>()); //Using Linq to json to extract CourseView

}


Remember that readable and simple code is much better than code that's complex and difficult to read. By using JSON fragments it makes your code much more readable and easier to maintain.



PopulateObject

With JSON fragments you're able to extract and work with sections of a large JSON object. PopulateObject is the opposite functionality where you're able to write specific values to a large JSON object.


List<UserInteraction> userLogs = GetTestData(); //Generate huge data


string jsonReviewed = "{'reviewed' : true. 'processedBy' : [''ReviewerProcess'], 'reviewedDate : '" + DateTime.Now.ToUniversalTime().ToString("yyyy-mm-ddTHH:mm:ssK") + @"' }";


foreach(UserInteraction log in userLogs)

{

JsonConvert.PopulateObject(jsonReviewed, log);

}



JSON Merge (Merge JSON Objects) (Skip)

There are cases where you have two JSON objects that you need to merge. For example, we might have a large JSON array where each item might need to read an object from a different data source. This can be a complex operation or not. Json.NET provides the merge functionality from one object to another. Logic is very simple. Name value pairs are copied across, skipping nulls if the existing property is not null and you can even specify how to handle arrays via merge array handling. You have four options for arrays, concat, union, replace, and merge.



Attributes for performance (Serialize and Deserialize Only What You Need) (Skip)

JsonIgnore Attributes on class



Optimizing Memory Usage (Avoid Large Object Heap, Use Streams)

Memory usage is critical to performance, but more than that, it can lead to exceptions. Any object over 85 kilobytes in size goes directly to a large object heap and this can mean a few out of memory exception. This number(85) is a threshold that was obtained after multiple tests by Microsoft. The problem with the large object heap as opposed to heap generations 0, 1, and 2, is that it's not compacted and even though there are some improvements in .NET Framework 4.5 and up, the promise that your memory usage may grow and grow until your application can be in trouble. Json.NET helps you improve memory usage by using streams instead of loading entire strings into memory. It achieves this by reading from a client in a synchronous way, reading one piece at a time a large JSON.


using (StreamReader streamReader = new StreamReader(stream))

{

using (JsonReader jsonReader = new JsonTextReader(streamReader))

{

var jsonSerializer = new JsonSerializer();

List<UserInteraction> logsStream = jsonSerializer.Deserialize<List<UserInteraction>>(jsonReader);


//The key here is that we're loading the text in an asynchronous way

}

}


출처

이 모든 내용은 Pluralsight에 Xavier Morera가 올린 'Getting Started with JSON in C# Using Json.NET'라는 강의의 다섯번째 챕터를 듣고 정리한 것입니다(https://app.pluralsight.com/library/courses/json-csharp-jsondotnet-getting-started/table-of-contents). 제가 정리한 것보다 더 많은 내용과 Demo를 포함하고 있으며 최종 Summary는 생략하겠습니다. Microsoft 지원을 통해 한달간 무료로 Pluralsight의 강의를 들으실 수도 있습니다.

'Programming > etc' 카테고리의 다른 글

(Json.NET) Custom Serialization  (0) 2018.03.30
(Json.NET) Settings & Attributes  (0) 2018.03.30
(Json.NET) Serialization Fundamentals  (0) 2018.03.30
AND

Copyright

이 모든 내용은 Pluralsight에 Xavier Morera가 올린 'Getting Started with JSON in C# Using Json.NET'라는 강의의 네번째 챕터를 듣고 정리한 것입니다(https://app.pluralsight.com/library/courses/json-csharp-jsondotnet-getting-started/table-of-contents).


Content

Serialization Fundamentals

Settings & Attributes

Custom Serialization

Performance Tips

LINQ to JSON

JSON & XML

Binary JSON (BSON)

Json.NET Schema


Outline

Conditional Serialization

Custom JsonConverter

Callbacks

ITraceWriter for logging and debugging



Conditional Serialization

Conditional serialization may not be the case that you want to serialize an object as is, but instead only serialize based on specific conditions and this is what conditional serialization is for.


You can specify conditions in your code using ShouldSerialize which works by creating a function with a bool return type that has the name ShouldSerialize and the property name.


public class AuthorSS

{

public string Name { get; set; }

public bool IsActive { get; set; }

public string[] Courses { get; set; }

public bool ShouldSerializeCourses()

{

//If Author IsActive then Courses will be serialized

return IsActive;

}

}


target class(AuthorSS) to serialize has to have boolean member(IsActive) with bool ShouldSerialize"TargetMemberName"() method

Before Serializing the class, If IsActive set to true. then target member will be serialized. if not target member is not serialized.


Or you can use IContractResolver

The IContractResolver is very useful when you use classes that you have not defined or you do not want to add the ShouldSerialize methods to those classes, or if it's a third party code you can't modify the code or you decide you prefer to avoid placing attributes. 


public class SelectiveContractResolver : DefaultContractResolver

{

private IList<string> propertiesList = null;


public SelectiveContractResolver(IList<string> propertiesToSerialize)

{

propertiesList = propertiesToSerialize; //Get strings of property names which want to serialize

}


protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)

{

IList<JsonProperty> properties = base.CreateProperties(type, memberSerialization);

return properties.Where(p => propertiesList.Contains(p.PropertyName)).ToList();

}

}


...

var contractResolver = new SelectiveContractResolver(propertiesToSerialize); //propertiesToSerialize is list of property name

string jsonstring = JsonConvert.SerializeObject(author, new JsonSerializerSettings

{

Formatting = Formatting.Indented,

ContractResolver = contractResolver

});



Custom JsonConverter

Json.NET provides JsonConvert as an easy to use wrapper over the JsonSerializer class to allow quick and easy conversion between .NET and JSON text. however, it may be possible that you want to extend or customize the serialization and deserialization process with a custom JSON converter based on the JsonConvert to fit exactly to your needs by overriding methods as required.


The JsonConverter class is the class responsible of converting from an object to JSON text and vice versa. It is extremely useful and easy to use, but what happens if you want to have finer control over the serialization and deserialization process? Well, you can create your own CustomJsonConverter class.


1. Create your own converter

2. Derived from JsonConvert

3. Override methods as needed

4. Set JsonSerializerSettings.Converters as a List<JsonConverter> with own custom converter



Callbacks

Serialization callbacks are methods that are raised before and after the serialization and deserialization process. They let you manipulate the objects or perform any operation before and after. A good example for using serialization callbacks is if you want it to have a functionality that logs the serialization time. The methods are OnSerializing and OnDeserializing, which are called before the conversion takes placed and OnSerialized and OnDeserialized which are called when the process completes.


public class Author

{

private Stopwatch timer = new Stopwatch();


public int age;

public string name { get; set; }

...


[OnSerializing]

internal void OnSerializingMethod(StreamingContext context)

{

timer.Reset(); timer.Start();

}


[OnSerialized]

internal void OnSerializedMethod(StreamingContext context)

{

timer.Stop();

}


[OnDeserializing]

internal void OnDeserializingMethod(StreamingContext context)

{

timer.Reset(); timer.Start();

}


[OnDeserialized]

internal void OnDeserializedMethod(StreamingContext context)

{

timer.Stop();

}

}



Logging and Debugging with ITraceWriter (Skip)

Debugging the serializer is not a common scenario, as in most cases everything just works, but what if you wanted to debug or if you want to understand exactly the serialization process, or you're running into an error and can't figure out what is the cause? Then you need the ITraceWriter. ITraceWriter is the method used for debugging the serialization process. Json.NET comes with a MemoryTraceWriter which logs all debugging information in memory. It's quick and easy to use or you can create your own custom TraceWriter.



출처

이 모든 내용은 Pluralsight에 Xavier Morera가 올린 'Getting Started with JSON in C# Using Json.NET'라는 강의의 네번째 챕터를 듣고 정리한 것입니다(https://app.pluralsight.com/library/courses/json-csharp-jsondotnet-getting-started/table-of-contents). 제가 정리한 것보다 더 많은 내용과 Demo를 포함하고 있으며 최종 Summary는 생략하겠습니다. Microsoft 지원을 통해 한달간 무료로 Pluralsight의 강의를 들으실 수도 있습니다.

'Programming > etc' 카테고리의 다른 글

(Json.NET) Performance Tips  (0) 2018.03.30
(Json.NET) Settings & Attributes  (0) 2018.03.30
(Json.NET) Serialization Fundamentals  (0) 2018.03.30
AND

Copyright

이 모든 내용은 Pluralsight에 Xavier Morera가 올린 'Getting Started with JSON in C# Using Json.NET'라는 강의의 세번째 챕터를 듣고 정리한 것입니다(https://app.pluralsight.com/library/courses/json-csharp-jsondotnet-getting-started/table-of-contents).


Content

Serialization Fundamentals

Settings & Attributes

Custom Serialization

Performance Tips

LINQ to JSON

JSON & XML

Binary JSON (BSON)

Json.NET Schema


Outline

Settings and Attributes

Settings

Attributes


Settings and Attributes

A setting is a user preference that is supplied during the conversion process. It can be specified as a property on the JsonSerializer class or using the JsonSerializer settings on JsonConvert.


An attribute is a declarative tag that is supplied on classes, properties, and more, that is taking into account during the serialization and deserialization process.



Settings

DateFormatHandling

With DateFormatHandling you tell Json.NET how to handle dates. e.g., the ISO date format or the Microsoft date format.


MissingMemberHandling

With MissingMemberHandling you tell Json.NET what to do when the JSON contains a member that is not defined. You can ignore or you can raise an error.


ReferenceLoopHandling

With ReferenceLoopHandling you tell Json.NET what to do when there is an object that references itself. You can ignore, raise an error, or serialize.


NullValueHandling

With NullValueHandling you tell Json.NET what to do when it runs into null values, both on serialization and deserialization.


DefaultValueHandling

With DefaultValueHandling you specify how to use the default values that are set using the DefaultValue attribute. [DefaultValue(3)] int defaultAgeIsThree;

Can ignore property which was set to default value when Serializing

Can populate default value to a property when Deserializing


ObjectCreationHandling

With ObjectCreationHandling you tell Json.NET how to handle objects that are created during the deserialization. By default, Json.NET sets values and appends values to existing collections. This might be the desired behavior in some cases, but in others it might not. You can specify if you want to reuse or replace the objects or collections that are set. This is particularly useful when you have constructors that populate values before the deserialization process.


TypeNameHandling

TypeNameHandling is very important because it tells Json.NET to preserve type information that's very useful when you're serializing and deserializing.


TypeNameAssemblyFormat

With TypeNameAssembly you tell Json.NET how you want type names written during the serialization process.


Binder

With Binder you tell Json.NET how to resolve type names to .NET types.


MetadataPropertyHandling


ConstructorHandling

ConstructorHandling is a way of telling Json.NET to specify which constructor to use, even if it's not a public constructor.


Converters

Converters is a way of telling Json.NET which converters you want to use during the deserialization and serialization process.


ContractResolver

With ContractResolver you specify to Json.NET how you want to control the serialization and deserialization without having attributes in your classes.


TraceWriter

TraceWriter is used for logging and debugging, and with Error you specify to Json.NET how is it that you want to handle errors.


Error

With Error you specify to Json.NET how is it that you want to handle errors.



Attributes

Attributes are declarative tags that are placed on classes, properties, and more and they provide additional information to Json.NET on how to do the serialization and deserialization process.


in Json.NET

JsonObjectAttribute

The JsonObjectAttribute is placed on classes to tell Json.NET how to serialize as a JsonObject.


JsonArrayAttribute

The JsonArrayAttribute is placed in collections and it tells Json.NET to serialize as a JsonArray.


JsonDictionaryAttribute

The JsonDictionaryAttribute is placed in dictionaries and it tells Json.NET how they should be serialized as JSON objects.


JsonPropertyAttribute

The JsonPropertyAttribute is used in fields and properties to control how they're serialized as properties in JsonObjects.


+ [JsonProperty(PropertyName = "AuthorName", Required = Required.Always, Order = 2)]

public string name { get; set; } 


If Json.NET try to serialize the class without value of above property(name) throws an error - Useful when a specific member to be set before serialize.

And Serialized PropertyName set to "AuthorName". Setting PropertyName can be implicit like below "WhereInTheWorld"


+ [JsonProperty("WhereInTheWorld", DefaultValueHandling = DefaultValueHandling.Ignore)]

[DefaultValue("Costa Rica")]

public string location { get; set; }


if location property is set to "Costa Rica" just as same as DefaultValue above, then DefaultValueHandling.Ignore Attribute makes Json.NET not to serialize location property at all. It's useful to save some bytes.


JsonIgnoreAttribute

JsonIgnore tells Json.NET to ignore and do not include a property during serialization.



MemberSerialization OptIn, OptOut, Fields


[JsonObject(MemberSerialization = MemberSerialization.OptIn)] //Only JsonProperty attached member is serialized

[JsonObject(MemberSerialization = MemberSerialization.OptOut)] //Just looking for which ones to ignore

[JsonObject(MemberSerialization = MemberSerialization.Field)] //Add some string on autogenerated field 

public class AuthorJsonObjectOptIn

{

private string privateField;

[JsonProperty] private string privateFieldWithAttribute; //private field also serialized

[JsonProperty] public string name { get; set; }            //Only this two member get serialize

public string[] courses { get; set; }

public DateTime since;

[NonSerialized] public bool happy;                //Ignore this two member and serialize else including private member

[JsonIgnoreAttribute] public object issues { get; set; }

}



JsonConverterAttribute

The JsonConverter can be placed on classes, fields, or properties and it tells Json.NET to use a specific JsonConverter during the serialization process.


e.g. [JsonConverter(typeof(StringEnumConverter))] public Relationship relationship { get; set; }  //Relationship is of type enum

if no Converter here, Json.NET serialize relationship(of type enum) as string like 1 or 2...

But with this converter it uses text in enum


JsonExtensionDataAttribute

The JsonExtensionDataAttribute is placed on a collection field or property and it tells Json.NET to use this as a catchall bucket to include any properties that do not have any matching class members.


JsonConstructorAttribute

The JsonConstructor attribute is placed on a constructor and it tells Json.NET to use this constructor during deserialization.



in Standard .NET Attributes

SerializableAttribute

The SerializableAttribute is used to indicate that a class can be serialized.


DataContractAttribute

The DataContractAttribute is used to specify that the type or class implements a data contract and is serializable.


DataMemberAttribute

 The DataMemberAttribute which when applied to a member of a type specifies that the member is part of a data contract.


NonSerializedAttribute

NonSerializedAttribute which tells Json.NET that a particular field should not be serialized.



출처

이 모든 내용은 Pluralsight에 Xavier Morera가 올린 'Getting Started with JSON in C# Using Json.NET'라는 강의의 세번째 챕터를 듣고 정리한 것입니다(https://app.pluralsight.com/library/courses/json-csharp-jsondotnet-getting-started/table-of-contents). 제가 정리한 것보다 더 많은 내용과 Demo를 포함하고 있으며 최종 Summary는 생략하겠습니다. Microsoft 지원을 통해 한달간 무료로 Pluralsight의 강의를 들으실 수도 있습니다.

'Programming > etc' 카테고리의 다른 글

(Json.NET) Performance Tips  (0) 2018.03.30
(Json.NET) Custom Serialization  (0) 2018.03.30
(Json.NET) Serialization Fundamentals  (0) 2018.03.30
AND

ARTICLE CATEGORY

분류 전체보기 (56)
Programming (45)
MSDN (4)
개발노트 (2)
reference (5)

RECENT ARTICLE

RECENT COMMENT

CALENDAR

«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30

ARCHIVE