What formatters do is format your response and request in your preferred data formats. For example, JSON
formatters; if used, would format your response (returned value from controller's action) and request (value passed as a parameter to the controller) in JSON
. The same goes for the XML
and other formatters. Out of the box, .NET
provides some response data formatters. This official documentation described them briefly.
But let’s not talk too much about formatters; rather let's see how we can make one. I think that’s what we are here for, right? Yeah! Let’s get started.
We have two abstract classes provided by the framework, InputFormmeter
, and OutputFormatter
. You would want to extend from these classes to make your custom formatters. To make things a bit easier to work with responses that are simple string representations of data formats there are two other abstract formatter classes i.e. TextInputFormatter
and TextOuputFormatter
.
When using the Yaml
output formatter you would get the response out of the current HttpContext
and serialize them into raw Yaml
response text. Pretty much the same goes for the input formatter. In this case, you would deserialize the Yaml
content from the request and use them in a generic form. Another important thing is that you have to explicitly set a media type header for these formatters. Doing that will activate the formatters whenever a client defines an Accept
header (for output) and Content-Type
(for input) with that specific media type format e.g. application/x-yaml
.
If you don’t want to use those headers while calling your controller’s actions you can explicitly define the type of the formatter that should be used while getting or posting content. For example, the [Produces("application/x-yaml")]
will return the response in Yaml
format whether you define an Accept
header or not. Again using the [Consumes("application/x-yaml")]
attribute would only accept Yaml content whether you define the Content-Type
or not.
By the way, I’m using the YamlDotNet
library from @antoineaubry for Yaml’s serializing and deserializing process.
Yaml Output Formatter
The code is pretty much self-explanatory. Get the Yaml
content from the request body and deserialize them into a generic type and you are done.
The same goes for the input formatter. In this case, you would serialize the Yaml content from the client's request and use them in a generic form.
Yaml Input Formatter
MediaTypeHeaderValues
a class where I've set up all the media type headers for my application.
internal class MediaTypeHeaderValues
{
public static readonly MediaTypeHeaderValue ApplicationYaml
= MediaTypeHeaderValue.Parse("application/x-yaml").CopyAsReadOnly();
public static readonly MediaTypeHeaderValue TextYaml
= MediaTypeHeaderValue.Parse("text/yaml").CopyAsReadOnly();
}
Notice that the YamlInputFormatter
’s constructor is accepting a Deserializer
where YamlOutputFormatter
is accepting a Serializer
. You can build the serialize and deserializer with some options while configuring the formatters in the Startup.cs
.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers(options => {
options.InputFormatters.Add(new YamlInputFormatter(new DeserializerBuilder().WithNamingConvention(namingConvention: new CamelCaseNamingConvention()).Build()));
options.OutputFormatters.Add(new YamlOutputFormatter(new SerializerBuilder().WithNamingConvention(namingConvention: new CamelCaseNamingConvention()).Build()));
options.FormatterMappings.SetMediaTypeMappingForFormat("yaml", MediaTypeHeaderValues.ApplicationYaml);
});
}
A GET
request with Accept
header set to application/x-yaml
Request
-------
curl -X 'GET' \
'http://localhost:5000/api/Geeks' \
-H 'accept: application/x-yaml'
Response
--------
- id: 1
name: Fiyaz
expertise: Javascript
rating: 4.0
- id: 2
name: Rick
expertise: .Net
rating: 5.0
A POST
request with Content-Type
header set to application/x-yaml
curl -X 'POST' \
'http://localhost:5000/api/Geeks' \
-H 'accept: application/x-yaml' \
-H 'Content-Type: application/x-yaml' \
-d 'id: 3
name: Jon Doe
expertise: Lorem Ipsum
rating: 5'
FormatterMappings
lets you call an action
with a specific format defined in a URL segment.
You can call the action like,
http://appurl/geeks.yaml
to get the response in Yaml
Or you can call it like,
http://appurl/geeks.json
to get the response in JSON
format.
And that’s it. This is all you need to know about building custom formatters in .NET
. You can find a bunch of other formatters from other awesome community members scattered around the web if you want.
Comments