Analysis on formatter of ASP. NET web API

Source: Internet
Author: User
Document directory
  • (1) constructor without parameters is missing
  • (2) The type is not defined as public.

The content of this article comes from: http://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization

I add some additional instructions and opinions to my dog's tail, maybe I am not good at English.

The difference between the web API of Asp.net and the traditional MVC website is that there is more formatter. In fact, formatter is not anything new, I think it is just another method to bind a model. Simply put, HTTP data is sent.. Net object. People who have done MVC model binding on MVC websites should be familiar with it. They are trying to find some key-value pairs of "Key = value" in the HTTP request. According to some conventions, matches the attribute or action parameter of the model. If there is a value type (such as INT) attribute in the model but it is not in the HTTP request, an argumentexception exception occurs, ysod (yellow screen of death) is displayed by default ).

I want Microsoft to get the formatter because it wants to make data binding more scalable. Imagine: You can use the formatter to customize the date output format. Through the formatter, convert a string into a small PNG Image for output, and define data more clearly and clearly.

1. What formatter are there?

Create a default mvc4 web API project and add the following to webapiconfig:

    foreach (var fmt in config.Formatters)    {        System.Diagnostics.Debug.WriteLine(fmt.GetType());    }

By default, you can see in the output window:

System. net. http. Formatting. jsonmediatypeformatter
System. net. http. Formatting. xmlmediatypeformatter
System. net. http. Formatting. formurlencodedmediatypeformatter
System. Web. http. modelbinding. jquerymvcformurlencodedformatter

As you can see, jsonmediatypeformatter is used for JSON serialization/deserialization, and xmlmediatypeformatter is used for XML serialization/deserialization, formurlencodedmediatypeformatter is used to process Request Parameters with URLs. The processing content of jquerymvcformurlencodedformatter should be related to form data.

2. How does a web API process XML?

At first, I thought that the web API used system. xml. xmlserializer to process XML, but later I found that it was not (not by default ). The simple evidence is:

Xmlserializer Cannot serialize ienumerable by default. It will report an error saying that ienumerable is an interface. If you want to serialize, I'm afraid you have to implement the ixmlserializable interface by yourself. However, by default, web APIs can serialize ienumerable <order> to XML and return it to the client. What XML serializer does the web API use by default? -- Datacontractserializer.

Create a simple console program and test it with the following code:

    IEnumerable<string> testobj = new string[] { "aaa", "bbb", "ccc" };    DataContractSerializer ser = new DataContractSerializer(testobj.GetType());    ser.WriteObject(Console.OpenStandardOutput(), testobj);    //Error    //XmlSerializer ser = new XmlSerializer(test.GetType());    //ser.Serialize(Console.Out, test);

I personally think it is better to use datacontractserializer, that is, the default settings of Web APIs. Obviously, it is too necessary to serialize ienumerable. However, some people who are used to xmlserializer-related serialization features (such as [xmlattribute], [xmlroot], and [xmlelement]) prefer xmlserializer. It is easy to do so, only webapiconfig. add to CS:

config.Formatters.XmlFormatter.UseXmlSerializer = true;

The serialization features of datacontractserializer are also very rich, and relevant articles on WCF will have a very detailed description, which will not be expanded here.

3. xml or JSON?

The web API is automatically selected based on the HTTP header of the Request Message:

Accept: Application/JSON
Content-Type: Application/JSON

Content-Type indicates the data type in the Request body, whether it is JSON or XML, or an image or something. Accept indicates the expected data type of the request. The above request indicates that the data in the Request Message Body is JSON, and the expected data type is JSON. To use XML, you can simply change application/JSON to application/XML.

I found through experiments that there is another rule for Web APIs: if the requested data type cannot be obtained for some reason, try to return it with another data type. For example, if XML is requested and XML encounters a problem during serialization, the web API will try to return data in JSON format.

Iv. possible causes of XML serialization failure

XML and JSON. I prefer JSON. Because of its conciseness, XML contains too many labels, schemas, and namespaces, which are easy to get dazzled. However, some clients are more convenient in processing XML, therefore, we still need to consider the XML serialization problem.

(1) constructor without parameters is missing

If your class lacks constructor without parameters, an error will be reported when it is serialized into XML. I cannot understand why, what do I need a constructor without parameters? Is it okay to serialize the serialized content directly? Let's take a minute to read it! I can't figure out why. If you can figure it out, it means you're smarter than me ...... OK. The reason is actually very simple: deserialization!

(2) The type is not defined as public.

The possible reason for this restriction is that the serializer believes that non-public type serialization will damage data encapsulation.

V. JSON serializer and the format of controlling time and date

The official version of mvc4 differs from the previous beta version. One of them is to use newtonsoft as the default JSON serializer. JSON, it seems that Microsoft is very open now, and they have begun to add third-party libraries to their own development environments. However, you need to know that newtonsoft. JSON is constantly updated. It is best to use nuget to obtain the latest version.

I personally think newtonsoft. JSON is quite good, and supports ienumerable, idictionary and Other interfaces very well. Below is a simple console example. We can use it to observe JSON serialization:

Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(testObject)); 

Is it very simple to have only one row? Specific Use of newtonsoft. JSON can refer to its official site: http://json.codeplex.com

One of the issues that I should note here is about the JSON date format. As we all know, most clients using JSON are browsers, the processing capability of browser JavaScript to date format is far worse than that of C #/Java. By default, the date is serialized as "2012-10-12t13: 18: 20.1656358 + 08: 00 "is obviously not friendly. If I just want to display" 2012-10-12 ", do I have to use JavaScript to extract the first 10 characters from this string? This is not elegant and cannot be guaranteed to be feasible. What if the default format is not like this? Right. Later, I developed a method to solve this problem (it took a lot of time to search, cough ......), Let's add some materials to newtonsoft. JSON:

namespace Newtonsoft.Json.Converters{    public class SimpleDateConverter : DateTimeConverterBase    {        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)        {            DateTime date = new DateTime();            DateTime.TryParse((string)reader.Value, out date);            return date;        }        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)        {            writer.WriteValue(((DateTime)value).ToString("yyyy-MM-dd"));        }    }}

Then modify the attributes of the datetime type as follows:

    [JsonConverter(typeof(SimpleDateConverter))]    public DateTime Dt {get;set;}
6. Test serialization and deserialization consistency

Serialization and deserialization must be consistent; otherwise, the program will be messy. How can we ensure this? Of course, it is a test. The article at the beginning of this article provides a very good method at the end of the article, which is easy to use, I will use the above Code here:

string Serialize<T>(MediaTypeFormatter formatter, T value){    // Create a dummy HTTP Content.    Stream stream = new MemoryStream();    var content = new StreamContent(stream);    /// Serialize the object.    formatter.WriteToStreamAsync(typeof(T), value, stream, content.Headers, null).Wait();    // Read 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 memory 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    return formatter.ReadFromStreamAsync(typeof(T), stream, null, null).Result as T;}// Example of usevoid 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    Person person2 = Deserialize<Person>(json, str);}

This code is well written!

7. Only XML or JSON is returned.

If you have special requirements, you can only return XML or only return JSON (although this is not recommended), you can remove the corresponding formatter. For example, you can remove the XML formatter (the code is written in webapiconfig. CS ):

    foreach (var fmt in config.Formatters)    {                System.Diagnostics.Debug.WriteLine(fmt.GetType());        if (fmt is System.Net.Http.Formatting.XmlMediaTypeFormatter)        {            config.Formatters.Remove(fmt);            break;        }    }

 

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.