| 

.NET C# Java Javascript Exception

9

In this seventh post I want to write about, how to send your Data in different formats and types to the client. By default the ASP.NET Core Web API sends the data as JSON, but there are some more ways to send the data.

The series topics

  • Customizing ASP.NET Core Part 01: Logging
  • Customizing ASP.NET Core Part 02: Configuration
  • Customizing ASP.NET Core Part 03: Dependency Injection
  • Customizing ASP.NET Core Part 04: HTTPS
  • Customizing ASP.NET Core Part 05: HostedServices
  • Customizing ASP.NET Core Part 06: Middleswares
  • Customizing ASP.NET Core Part 07: OutputFormatter - This article
  • Customizing ASP.NET Core Part 08: ModelBinders
  • Customizing ASP.NET Core Part 09: ActionFilter
  • Customizing ASP.NET Core Part 10: TagHelpers

About OutputFormatters

OutputFormatters are classes that turn your data into a different format to sent them trough HTTP to the clients. Web API uses a default OutputFormatter to turn objects into JSON, which is the default format to send data in a structured way. Other build in formatters are a XML formatter and a plan text formatter.

With the - so called - content negotiation the client is able to decide which format he wants to retrieve .The client need to specify the content type of the format in the Accept-Header. The content negotiation is implemented in the ObjectResult.

By default the Web API always returns JSON, even if you accept text/xml in the header. This is why the build in XML formatter is not registered by default. There are two ways to add a XmlSerializerOutputFormatter to ASP.NET Core:

services.AddMvc()
 .AddXmlSerializerFormatters();

or

services.AddMvc(options =>
{
 options.OutputFormatters.Add(new XmlSerializerOutputFormatter());
});

There is also a XmlDataContractSerializerOutputFormatter available

Also any Accept header gets turned into application/json. If you want to allow the clients to accept different headers, you need to switch that translation off:

services.AddMvc(options =>
{
 options.RespectBrowserAcceptHeader = true; // false by default
});

To try the formatters let's setup a small test project.

Prepare a test project

Using the console we will create a small ASP.NET Core Web API project. Execute the following commands line by line:

dotnet new webapi -n WebApiTest -o WebApiTest
cd WebApiTest
dotnet add package GenFu
dotnet add package CsvHelper

This creates a new Web API projects and adds two NuGet packages to it. GenFu is a awesome library to easily create test data. The second one helps us to easily write CSV data.

Now open the project in Visual Studio or in Visual Studio Code and open the ValuesController.cs and change the Get() method like this:

[HttpGet]
public ActionResult<IEnumerable<Person>> Get()
{
	var persons = A.ListOf<Person>(25);
	return persons;
}

This crates a list of 25 Persons using GenFu. The properties get automatically filled with almost realistic data. You'll see the magic of GenFu and the results later on.

In the Models folder create a new file Person.cs with the the Person class inside:

public class Person
{
 public int Id { get; set; }
 public string FirstName { get; set; }
 public string LastName { get; set; }
 public int Age { get; set; }
 public string EmailAddress { get; set; }
 public string Address { get; set; }
 public string City { get; set; }
 public string Phone { get; set; }
}

Open the Startup.cs as well and add the Xml formatters and allow other accept headers as described earlier:

services.AddMvc(options =>
{
 options.RespectBrowserAcceptHeader = true; // false by default
 options.OutputFormatters.Add(new XmlSerializerOutputFormatter());
});

That's it for now. Now you are able to retrieve the data from the Web API. Start the project by using the dotnet run command.

The best tools to test a web API are Fiddler or Postman. I prefer Postman because it is easy to use. At the end it doesn't matter which tool you want to use. In this demos I'm going to use Postman.

Inside Postman I create a new request. I write the API Url into the address field, which is https://localhost:5001/api/values and I add a header with the key Accept and the Value application/json.

After I press send I will see the JSON result in the response body below:

Here you can see the auto generated values. GenFu puts the data in based on the property type and the property name. So it puts real first names and real last names as well as real cities and phone numbers into the Persons properties.

No let's test the XML output formatter.

In postman change the Accept header form application/json to text/xml and press send:

We now have an XML formatted output.

Now let's go a step further and create some custom OutputFormatters.

Custom OutputFormatters

The plan is to create an VCard output to be able to import the persons contacts directly to outlook or any other contact database that supports VCards. Later in this section we also want to create an CSV output formatter.

Both are text based output formatters and will derive from TextOutputFormatter. Create a new class in a new file called VcardOutputFormatter.cs:

public class VcardOutputFormatter : TextOutputFormatter
{
 public string ContentType { get; }

 public VcardOutputFormatter()
 {
 SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("text/vcard"));

 SupportedEncodings.Add(Encoding.UTF8);
 SupportedEncodings.Add(Encoding.Unicode);
 }

 // optional, but makes sense to restrict to a specific condition
 protected override bool CanWriteType(Type type)
 {
 if (typeof(Person).IsAssignableFrom(type) 
 || typeof(IEnumerable<Person>).IsAssignableFrom(type))
 {
 return base.CanWriteType(type);
 }
 return false;
 }

 // this needs to be overwritten
 public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
 {
 var serviceProvider = context.HttpContext.RequestServices;
 var logger = serviceProvider.GetService(typeof(ILogger<VcardOutputFormatter>)) as ILogger;

 var response = context.HttpContext.Response;

 var buffer = new StringBuilder();
 if (context.Object is IEnumerable<Person>)
 {
 foreach (var person in context.Object as IEnumerable<Person>)
 {
 FormatVcard(buffer, person, logger);
 }
 }
 else
 {
 var person = context.Object as Person;
 FormatVcard(buffer, person, logger);
 }
 return response.WriteAsync(buffer.ToString());
 }

 private static void FormatVcard(StringBuilder buffer, Person person, ILogger logger)
 {
		buffer.AppendLine("BEGIN:VCARD");
		buffer.AppendLine("VERSION:2.1");
		buffer.AppendLine($"FN:{person.FirstName} {person.LastName}");
		buffer.AppendLine($"N:{person.LastName};{person.FirstName}");
		buffer.AppendLine($"EMAIL:{person.EmailAddress}");
		buffer.AppendLine($"TEL;TYPE=VOICE,HOME:{person.Phone}");
		buffer.AppendLine($"ADR;TYPE=home:;;{person.Address};{person.City}"); 
		buffer.AppendLine($"UID:{person.Id}");
		buffer.AppendLine("END:VCARD");
		logger.LogInformation($"Writing {person.FirstName} {person.LastName}");
 }
}

In the constructor we need to specify the supported media types and encodings. In the method CanWriteType() we need to check whether the current type is supported within this output formatters. Here we only want to format a single Person or a lists of Persons.

The method WriteResponseBodyAsync() then actually writes the list of persons out to the response stream via a StringBuilder

At least we need to register the new VcardOutputFormatter in the Startup.cs:

services.AddMvc(options =>
{
 options.RespectBrowserAcceptHeader = true; // false by default
 options.OutputFormatters.Add(new XmlSerializerOutputFormatter());
 
 // register the VcardOutputFormatter
 options.OutputFormatters.Add(new VcardOutputFormatter()); 
});

Start the app again using dotnet run. Now change the Accept header to text/vcard and let's see what happens:

We now should see our date in the VCard format.

Let's do the same for a CSV output. We already added the CsvHelper library to the project, so you can just copy the next snippet into your project:

public class CsvOutputFormatter : TextOutputFormatter
{
 public string ContentType { get; }

 public CsvOutputFormatter()
 {
 SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("text/csv"));

 SupportedEncodings.Add(Encoding.UTF8);
 SupportedEncodings.Add(Encoding.Unicode);
 }

 // optional, but makes sense to restrict to a specific condition
 protected override bool CanWriteType(Type type)
 {
 if (typeof(Person).IsAssignableFrom(type)
 || typeof(IEnumerable<Person>).IsAssignableFrom(type))
 {
 return base.CanWriteType(type);
 }
 return false;
 }

 // this needs to be overwritten
 public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
 {
 var serviceProvider = context.HttpContext.RequestServices;
 var logger = serviceProvider.GetService(typeof(ILogger<CsvOutputFormatter>)) as ILogger;

 var response = context.HttpContext.Response;

 var csv = new CsvWriter(new StreamWriter(response.Body));

 if (context.Object is IEnumerable<Person>)
 {
 var persons = context.Object as IEnumerable<Person>;
 csv.WriteRecords(persons);
 }
 else
 {
 var person = context.Object as Person;
 csv.WriteRecord<Person>(person);
 }

 return Task.CompletedTask;
 }
}

This almost works the same way. We can pass the response stream via a StreamWriter directly into the CsvWriter. After that we are able to feed the writer with the persons or the list of persons. That's it.

We also need to register the CsvOutputFormatter before we can test it.

services.AddMvc(options =>
{
 options.RespectBrowserAcceptHeader = true; // false by default
 options.OutputFormatters.Add(new XmlSerializerOutputFormatter());
 
 // register the VcardOutputFormatter
 options.OutputFormatters.Add(new VcardOutputFormatter()); 
	// register the CsvOutputFormatter
 options.OutputFormatters.Add(new CsvOutputFormatter()); 
});

In Postman change the Accept header to text/csv and press send again:

Conclusion

Isn't that cool? I really like the way to change the format based on the except header. This way you are able to create an Web API for many different clients and that accept many different formats. There are still a lot of potential clients outside which don't use JSON and prefer XML or CSV.

The other way around would be an option to consume CSV or any other format inside the Web API. Let's assume your client would send you a list of persons in CSV format. How would you solve this? Parsing the String manually in the action method would work, but it's not a nice option. This is what ModelBinders can do for us. Let's see how this works in the next chapter about Customizing ASP.NET Core Part 08: ModelBinders.

.net visual-studio csharp asp.net
Weitere News:
13 Meinungen
0
Thanks for sharing.I found a lot of interesting information here. A really good post, very thankful and hopeful that you will write many more posts like this one.
ucbrowser.vip shareit.onl mxplayer.pro
0
The Formatter class supports format operations on output (strings, dates, time, local-specific data). Perhaps you'd like to output large floating pointer numbers in scientific notation or today's date in a non-traditional format.Write my essay for me UK
0
If you are searching Assignment help.You can suggest them to use different online sources to develop the reading habit in them. Using different online sources can be beneficial for their assignment help for a long run. Organise each topic in a story form to develop their interest in the class.Assignment help
0
Studies show that around 56% of all students consider their homework as the most primary source of stress in their life. It is no wonder then these students constantly think of ‘who can do my homework’ in UK. Fortunately for them, we provide expert homework help at very reasonable prices. Recent research has also revealed that on average students between the ages of 6 to 17 have to spend a little more than three and a half hours each day of their school life doing homework. Our aim is to cut the time you spent doing your homework by more than a half by offering homework help online services in UK to students. We offer you with several extraordinary benefits that make us the best choice for you.
0
Sometimes, students, have an absence of your time associate degreed don't ready to complete an assignment. Then uaeassignmenthelp.com offer cheap essay writing help UAE. As a result of our company is that the best-trusted brand. Simply send associate degree email info@uaeassignmenthelp.com
0
I have been working as a full time academic consultant from last seven years. I am dedicatedly working at MyAssignmentHelpAu to help students with their entire academic writing requirements. I offered writing help to the students who are struggling with their academic writing tasks. I possess a good writing and researching skills and thus I am liable to provide the best My Assignment Help Australia scholastic guidance to the students.
0
Assignment help is an online assignment help from singaporeassignmenthelp.com. Get essay writing service singapore support form no 1 assignment providing company of Singapore at a cheap price.
0
I am the assignment help provider at My assignment help. I have done P.hD in the computers if a student has an issue regarding the assignment writing then may take help from the assignment assistance services.
0
If you are in need for online writing assistance for an intricate thesis topic, then avail prime assignment writing service in Australia and save your time to relax and do your studies properly. Their cdr australia help online service has earned huge popularity among both domestic and international students. You can contact them now to buy assignment help online. Leave your tensions and enjoy your free time.
0
We are the most important assignment help in Canada offering the expert assistance in a variety of disciplines. The steady growth of Java Assignment Help in the industry is a clear indication of our ingenuity. We strive to meet the writing needs of every student with 100% original write-ups always delivered within the promised deadline.
0
If you need Essay help services from professional experts then, come at IrelandAssignmentHelp.com. We have native English speakers from Ireland in our team.
0
یکی از روش های جنتلمن شدن داشتن کیف پول چرم است که می توانید در اینترنت با جستجو در گوگل بهترین مارک های کیف پول چرم را یافته و از آنها تهیه کنید
یکی بهترین تولید کنندگان و عرضه کنندگان کیف پول فروشگاه تضمینی ها است که سابقه چند ده ساله در این زمینه دارد
بهتر است به این فروشگاه سر زده و از محصولات آنها استفاده نمایید
0
Complete your imagination of getting highest marks in your exam and be popular in college by taking help of students assignment help experts help on assignment help UAE.
Schreibe einen Kommentar:
Themen:
asp.net csharp visual-studio .net
Entweder einloggen... ...oder ohne Wartezeit registrieren
Benutzername
Passwort
Passwort wiederholen
E-Mail
TOP TECHNOLOGIES CONSULTING GmbH