Use System.Text.Json for JSON processing in ASP.NET Core
If you worked with earlier versions of ASP.NET MVC and ASP.NET Core, you are
probably aware that these versions use Json.NET library for the sake of JSON
processing. In ASP.NET Core 3 Microsoft has provided in-built support for JSON
serialization and deserialization. That means you no longer need to depend on
Json.NET library. The good part is, you can still use Json.NET if you so wish.
So, you have two options now as far as JSON processing is concerned - either use
in-built JSON API or use Json.NET. The in-built support for JSON serialization
and deserialization comes from System.Text.Json namespace. In this article you
will learn to use the System.Text.Json for serializing and deserializing JSON
data during Web API communication.
Recently Microsoft released ASP.NET Core 3 Preview 7. There are
a few changes in the JSON processing API. Parse() method is now Deserialize()
and ToString() method is now Serialize(). The following example has been updated
to use the new methods.
Customers Web API
Suppose you have Customers Web API that performs CRUD operations on Customers
table of Northwind database. Although I won't go into the basics of creating a
Web API in ASP.NET Core, the GET and PUT actions on the Web API are shown below:
[HttpGet("{id}")]
public Customer Get(string id)
{
return db.Customers.Find(id);
}
[HttpPut("{id}")]
public string Put(string id, [FromBody]Customer obj)
{
if (ModelState.IsValid)
{
db.Customers.Update(obj);
db.SaveChanges();
return "Success!";
}
else
{
return "Error!";
}
}
The Get() action returns a particular Customer to the caller whereas the
Put() action updates an existing Customer in the database. The Customer entity
class used by the above methods looks like this :
public class Customer
{
public string CustomerID {get; set;}
public string CompanyName {get; set;}
public string ContactName {get; set;}
public string Country {get; set;}
}
When you use the Get() action of the Customers API shown above, internally it
utilizes classes from System.Text.Json namespace to serialize the Customer
object to the client. It uses System.Text.Json classes by default and hence you
don't need to specifically do anything (unless you want to fine-tune the default
configuration). The serialized JSON data needs to be deserialized once it
reaches the client so that Customer object can be reconstructed.
In order to call the Put() action the client needs to serialize the Customer
object to be updated in the database. The serialized JSON data will be then
deserialized by the Web API while invoking the Put() action.
Deserializing JSON data using Deserialize() method
Now, suppose that you want to build a client application that uses .NET
Core's HttpClient class to invoke the Get() and Put() actions. So, first step
would be to use these namespaces:
using System.Text.Json;
using System.Text.Json.Serialization;
Especially the System.Text.Json.Serialization namespace is important for this
example because it provides certain classes (discussed shortly) to serialize and
deserialize the JSON data. Let's see how that can be done.
Consider the following code that invokes the Get() action of the Customers
Web API.
public void GetCustomer()
{
HttpResponseMessage response =
client.GetAsync("http://localhost/api/customers/ALFKI")
.Result;
string stringData = response.Content.
ReadAsStringAsync().Result;
var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};
Customer obj = JsonSerializer.Deserialize<Customer>
(stringData, options);
// do something with obj
}
The GetCustomer() method invokes the Customers Web API by making a GET
request using GetAsync() method. It also passes ALFKI as the CustomerID to be
retrieved. The Customer data is returned from the Web API and is read using the
ReadAsStringAsync() method. The string returned by ReadAsStringAsync() method
contains JSON serialized customer data. This string data needs to be
deserialized into a Customer object so that it can be used further in the client
application.
To deserialize the JSON data the code uses Deserialize<T>() method of JsonSerializer class from System.Text.Json.Serialization namespace. The
Deserialize<T>() method takes the string JSON data and settings to be used while deserializing the data. The settings are supplied through JsonSerializerOptions
class. When a Customer object is returned by the Web API, the serialized
property names use camel casing. While deserializing the data you need to tell
the JsonSerializer class that deserialization should ignore the character
casing. So, PropertyNameCaseInsensitive property of
JsonSerializerOptions is set to true.
If the Deserialize() method is successful the obj will contain a Customer object
and you can use it further in the code as per your requirement.
Serializing object as JSON string using Serialize() method
Now let's see how JSON data can be sent from the client to the Web API.
Consider the following code that invokes the Put() action of the Web API.
public void UpdateCustomer()
{
Customer obj = new Customer();
obj.CustomerID = "ALFKI";
obj.CompanyName = "Company 1";
obj.ContactName = "Contact 1";
obj.Country = "USA";
string stringData = JsonSerializer.Serialize(obj);
var contentData = new StringContent(stringData,
System.Text.Encoding.UTF8, "application/json");
HttpResponseMessage response = client.PutAsync
("http://localhost/api/customers/ALFKI", contentData)
.Result;
string msg = JsonSerializer.Deserialize<string>
(response.Content.ReadAsStringAsync().Result);
}
The UpdateCustomer() method creates a Customer object. To send this object to
the Web API, first you need to serialize it into JSON format. This is done using
the Serialize() method of JsonSerializer class. The string data returned by the
Serialize() method is wrapped into a StringContent object and then passed to the
PutAsync() method. The success or error string message returned by the Put()
action is read using the Deserialize() method discussed earlier.
The JsonSerializer class also supports asynchronous operations through
SerializeAsync() and DeserializeAsync() methods.
That's it for now! Keep coding!!