ASP 2 13th Lesson--asp.net JSON and XML serialization in the Web API

Source: Internet
Author: User
Tags iso 8601 iso 8601 format local time object serialization

Objective

Before reading this article, you can also go to the ASP. NET Web API 2 series navigation to view http://www.cnblogs.com/aehyok/p/3446289.html

This article describes the JSON and XML formatters in the ASP.

In the ASP. NET Web API, the media type formatter (Media-type Formatter) is an object that can do the following:

    • Reading CLR (Common language Runtime) objects from the HTTP message body
    • Writing CLR objects to the HTTP message body

The Web API provides a media type formatter for JSON and XML. The framework already inserts these formatters into the message processing pipeline by default. The client can request JSON or XML in the Accept header of the HTTP request.

JSON Media type Formatter

JSON formatting is provided by the Jsonmediatypeformatter class. By default,Jsonmediatypeformatter uses the Json.NET library to perform serialization work. Json.NET is a third-party open source project.

If you like, you can configure Jsonmediatypeformatter to use datacontractjsonserializer instead of json.net. To do this, just Usedatacontractjsonserializer set the property to true :

var json = Globalconfiguration.configuration.formatters.jsonformatter;json. Usedatacontractjsonserializer = true;
JSON serialization

This section describes some of the specific behavior of the JSON formatter when using the default Json.NET serializer. This does not mean that you want to include the entire document for the Json.NET library. See Json.NET documentation for more information.

What will be serialized?

By default, all public properties and fields are included in the serialized JSON. to ignore a property or field, you need to decorate it with the jsonignore annotation property.

public class product{Public    string Name {get; set;}    Public decimal price {get; set;}    [Jsonignore]    public int ProductCode {get; set;}//omitted}

If you prefer the opt-in (optional) method, you can use the datacontract annotation property to decorate the class. If there are annotation attributes, the members are ignored unless there is a DataMember. DataMember can also serialize private members.

[Datacontract]public class product{    [DataMember] public    string Name {get; set;}    [DataMember]    Public decimal price {get; set;}    public int ProductCode {get; set;}  omitted by default}
Read-only properties

Read-only properties are serialized by default.

Dates (date)

By default, Json.NET will write the date in ISO 8601 format. The date in UTC (coordinated Universal time-World Standard Time) format is written with the suffix "Z". The date in the local time format includes a time zone offset. For example:

2012-07-27t18:51:45.53403z         //UTC (Standard Time) 2012-07-27t11:51:45.53403-07:00    //local (native time)

By default, Json.NET preserves the time zone. You can override this behavior by setting the Datetimezonehandling property:

Convert all dates to utc//converts all dates to the UTC format var json = Globalconfiguration.configuration.formatters.jsonformatter;json. serializersettings.datetimezonehandling =     NEWTONSOFT.JSON.DATETIMEZONEHANDLING.UTC;

If you prefer to use Microsoft's JSON date format ("\/date (ticks) \ \") instead of ISO 8601, you can set the dateformathandling property on Serializersettings:

var json = Globalconfiguration.configuration.formatters.jsonformatter;json. serializersettings.dateformathandling =    Newtonsoft.Json.DateFormatHandling.MicrosoftDateFormat;
Indenting (indent)

In order to write JSON with indentation, you can set formatting to formatting.indented:

var json = Globalconfiguration.configuration.formatters.jsonformatter;json. Serializersettings.formatting =     
Camel casing (Camel-case conversion)

In order to change the property name of the JSON with the camel-case case without modifying the data model, you can set the camelcasepropertynamescontractresolveron the serializer:

var json = Globalconfiguration.configuration.formatters.jsonformatter;json. Serializersettings.contractresolver =     new Camelcasepropertynamescontractresolver ();
Anonymous types and weakly typed objects

Action method or to return an anonymous object and serialize it to JSON. For example:

public Object Get () {    return new {         Name = ' Alice ', age         = all,         Pets = new List<string> {"Fido", "Polly "," Spot "}     };}

The response message body will contain the following JSON:

{"Name": "Alice", "age": +, "Pets": ["Fido", "Polly", "Spot"]}

If the Web API receives a loosely structured Json from the client, you can serialize the request body to the Newtonsoft.Json.Linq.JObject type.

public void Post (jobject person) {    string name = person["Name"]. ToString ();    int age = person["Age"]. Toobject<int> ();}

However, it is usually better to use strongly typed data objects. Then, you do not need to parse the data yourself, and you can get the benefits of model validation.

The XML serializer does not support anonymous types or jobject instances. If you use these attributes with JSON data, you should remove the XML formatter from the pipeline, as described later in this article.

XML Media Type Formatter

XML formatting is provided by the Xmlmediatypeformatter class. By default,Xmlmediatypeformatter uses the DataContractSerializer class to perform serialization. If you like, you can configure Xmlmediatypeformatter to use XmlSerializer instead of DataContractSerializer. To do this, you can set the Usexmlserializer property to true:

var xml = Globalconfiguration.configuration.formatters.xmlformatter;xml. Usexmlserializer = true;

The XmlSerializer class supports a narrower set of types than DataContractSerializer , but has more control over the resulting XML. If you need to match an existing XML schema, consider using XmlSerializer.

Serialization of XML Serialization--xml

This section describes some of the special behaviors of the XML formatter when using the default DataContractSerializer . By default, the DataContractSerializer behavior is as follows:

    • Serializes all public read/write properties and fields. To omit a property or field, decorate it with the ignoredatamember annotation property.
    • Private and protected members do not make sequences.
    • Read-only properties are not serialized
    • The class name and member name are written to the XML by the exact rendering in the class declaration
    • Using the default namespace for XML

If you need more control over serialization, you can use the datacontract annotation property to decorate the class. When this annotation attribute appears, the class is serialized by policy:

    • "Opt in" Method: Properties and fields are not serialized by default. To serialize a property or field, decorate it with the DataMember annotation property.
    • To serialize a private or protected member, decorate it with the DataMember annotation property.
    • Read-only properties are not serialized.
    • To change the rendering of the class name in XML, set the name parameter in the datacontract annotation property.
    • To change the rendering of member names in XML, set the nmae parameter in the DataMember annotation property.
    • To change the XML namespace, set the Namespace parameter in the DataContract class.

Read-only properties--Read-only property

Read-only properties are not serialized. If the read-only attribute has a support private field, you can mark the private field with the DataMember annotation property. This approach requires the use of the datacontract Annotation property on the class.

[Datacontract]public class product{    [DataMember]    private int pcode;  Serialized (serialized)    //Not serialized (READ-ONLY)    //Do not serialize (read-only) public    int ProductCode {get {return pcode;} }}
dates--Date

The date is written in ISO 8601 format. For example, "2012-05-23t20:21:37.9116538z".

indenting--Indent

To write the indented XML, set the Indent property to true:

Set the XML serializer for each type (Per-type)

You can set different XML serializers for different CLR types. For example, you might have a special data object that needs to be XmlSerializerfor backwards compatibility. You can use XmlSerializerfor this object and continue to use DataContractSerializerfor other types.

To set up an XML serializer for a special type, call Setserializer.

var xml = globalconfiguration.configuration.formatters.xmlformatter;//Use XmlSerializer for instances of type "Product" ://Use Xmlserializer:xml.setserializer<product> (New XmlSerializer (typeof (Product)) for instances of "Product" type;

You can specify a XmlSerializer, or any object that is derived from xmlobjectserializer .

Removing the JSON or XML formatter--to remove the JSON or XML formatter

You can remove the JSON formatter, or XML formatter, from the formatter list as long as you don't want to use them. The main reasons for doing this are:

    • Limit your Web API responses to specific media types. For example, you might decide to only support JSON responses and delete the XML formatter.
    • Replace the default formatter with a custom formatter. For example, you might want to replace the (default) JSON formatter with your own custom JSON formatter implementation.

The following code demonstrates how to delete the default formatter. It is called in the Application_Start method defined in Global.asax.

void Configureapi (httpconfiguration config) {    //Remove the JSON formatter    //delete JSON formatter    config. Formatters.remove (config. Formatters.jsonformatter);    or (or)    //Remove the XML formatter    //delete XML Formatter    config. Formatters.remove (config. Formatters.xmlformatter);}

Handling Circular Object references--processing circular objects Reference

By default, JSON and XML formatters write all objects as values. If two attributes refer to the same object, or if an object appears two times in a set contract, the formatter will serialize the object two times. This is a unique problem that occurs when the object graph contains loops, because the serializer throws an exception when it detects a loop in the object graph.

Consider the following object model and controller.

public class employee{Public    string Name {get; set;}    Public Department Department {get; set;}} public class department{Public    string Name {get; set;}    Public Employee Manager {get; set;}} public class departmentscontroller:apicontroller{Public    Department Get (int id)    {        Department sales = new De Partment () {Name = "Sales"};        Employee Alice = New Employee () {Name = "Alice", Department = sales};        Sales. Manager = Alice;        return sales;    }}

Calling this action triggers the formatter to throw an exception that translates into a status code 500 (internal server error) response sent to the client.

To preserve the object references in JSON, add the following code to the Application_Start method of the Global.asax file:

var json = Globalconfiguration.configuration.formatters.jsonformatter;json. serializersettings.preservereferenceshandling =     Newtonsoft.Json.PreserveReferencesHandling.All;

Now, this controller action returns JSON similar to the following form:

{"$id": "1", "name": "Sales", "Manager": {"$id": "2", "Name": "Alice", "Department": {"$ref": "1"}}

Notice that the serializer adds a "$id" to all two objects. Furthermore, it detects that the Employee.department property produces a loop, so it replaces this value with an object reference {"$ref": "1"}.

Object references are non-standard JSON. Before using this attribute, consider whether your client can resolve this result. Simply removing loops from the object graph can be a better approach. For example, in this example, the employee link back to department is not really needed.

To preserve the object references in the XML, you can use two options. The simpler option is to add [DataContract (Isreference=true)] to the model class. The isreference parameter has an object reference enabled. Remember thatDataContract makes up the serialized "opt-in", so you also need to add DataMember Annotation Properties to the property:

[DataContract (isreference=true)]public class department{    [DataMember] public    string Name {get; set;}    [DataMember]    Public Employee Manager {get; set;}}

Now, the formatter will produce XML similar to the following form:

<department xmlns:i= "http://www.w3.org/2001/XMLSchema-instance" z:id= "I1"             xmlns:z= "http// schemas.microsoft.com/2003/10/serialization/"             xmlns=" Http://schemas.datacontract.org/2004/07/Models ">    <Manager>        <department z:ref= "I1"/>        <Name>Alice</Name>    </Manager>    <Name>Sales</Name></Department>

If you want to avoid using annotation properties on model classes, there is another option: Create a new type-specific DataContractSerializer instance, and in the constructor preserveobjectreferences Set to true:

var xml = Globalconfiguration.configuration.formatters.xmlformatter;var DCs = new DataContractSerializer (typeof ( Department), NULL, int. MaxValue,    false,/* preserveobjectreferences: */true, null); XML. Setserializer<department> (DCs);

Testing object serialization--Test objects serialization

When designing a Web API, it is useful to test how objects are serialized. You do this without having to create a controller or invoke a controller action.

String serialize<t> (Mediatypeformatter formatter, T value) {//Create a dummy HTTP Content.    Create an HTTP content dummy stream stream = new MemoryStream ();    var content = new Streamcontent (stream);    Serialize the object. Serializes the object formatter. Writetostreamasync (typeof (T), value, stream, content. Headers, NULL).    Wait ();    Read the serialized string. Reads the serialized string stream.    Position = 0; return content. Readasstringasync (). Result;} T deserialize<t> (Mediatypeformatter Formatter, String str) where t:class{//Write the serialized string to a M    Emory Stream.    Writes the serialized character to the inner stream stream stream = new MemoryStream ();    StreamWriter writer = new StreamWriter (stream); Writer.    Write (str); Writer.    Flush (); Stream.    Position = 0; Deserialize to an object of type T///The object that is serialized into type T is return formatter. Readfromstreamasync (typeof (T), stream, NULL, NULL). Result as T;} Example of use//Use example (use case) void Testserialization () {var value = new Person () {Name = "Alice ", age = 23};    var xml = new Xmlmediatypeformatter ();    String str = Serialize (XML, value);    var json = new Jsonmediatypeformatter ();    str = Serialize (JSON, value); Round Trip//reverse operation (deserialization) person Person2 = deserialize<person> (JSON, str);}

Summarize

This lesson is a simple way to understand the use of serialization and deserialization of JSON and XML.

The reference link for this article is http://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization

At the same time this article has been updated to the Web API navigation series http://www.cnblogs.com/aehyok/p/3446289.html

ASP 2 13th Lesson--asp.net JSON and XML serialization in the Web API

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.