I would like to create a web application that returns data in the form of XML or JSON, how do I go about doing this?
The model:
namespace ReturningJSONandXML.Models
{
public class SomeImportantInformation
{
public int ID { get; set; }
public string Information { get; set; }
}
}
The controller:
namespace ReturningJSONandXML.Controllers
{
public class GetInfoController : Controller
{
// GET: /<controller>/
public List<SomeImportantInformation> Get()
{
List<SomeImportantInformation> ImportantInfo = new List<SomeImportantInformation>();
ImportantInfo.Add(new SomeImportantInformation { ID = 0, Information = "Awesome info" });
ImportantInfo.Add(new SomeImportantInformation { ID = 1, Information = "Some other interesting info" });
return ImportantInfo;
}
}
}
I would like to return an XML and JSON file...
What are the best practice's I should be using here?
The framework takes care automatically for you, so you don´t have to reinvent the wheel. The answer is quoted below. But to make it simpler: Unless you specify an Accept header, the API will serialize the response as JSON. If you specify for example 'application/xml' it will return XML. As MSDN Says:
Content negotiation (conneg for short) occurs when the client
specifies an Accept header. The default format used by ASP.NET Core
MVC is JSON. Content negotiation is implemented by ObjectResult. It is
also built into the status code specific action results returned from
the helper methods (which are all based on ObjectResult). You can also
return a model type (a class you've defined as your data transfer
type) and the framework will automatically wrap it in an ObjectResult
for you.
Content negotiation only takes place if an Accept header appears in
the request. When a request contains an accept header, the framework
will enumerate the media types in the accept header in preference
order and will try to find a formatter that can produce a response in
one of the formats specified by the accept header. In case no
formatter is found that can satisfy the client's request, the
framework will try to find the first formatter that can produce a
response (unless the developer has configured the option on MvcOptions
to return 406 Not Acceptable instead). If the request specifies XML,
but the XML formatter has not been configured, then the JSON formatter
will be used. More generally, if no formatter is configured that can
provide the requested format, then the first formatter than can format
the object is used. If no header is given, the first formatter that
can handle the object to be returned will be used to serialize the
response. In this case, there isn't any negotiation taking place - the
server is determining what format it will use.
https://docs.microsoft.com/en-us/aspnet/core/mvc/models/formatting
In ASP.Net Core 2.0 you can use eve shorter syntax.
In Startup class in ConfigureServices method, you should have:
services
.AddMvc()
.AddXmlSerializerFormatters();
And controller that accepts complex object looks like this:
[Route("api/Documents")]
public class DocumentsController : Controller
{
[Route("SendDocument")]
[HttpPost]
public ActionResult SendDocument([FromBody]DocumentDto document)
{
return Ok();
}
}
This is an XML to send:
<document>
<id>123456</id>
<content>This is document that I posted...</content>
<author>Michał Białecki</author>
<links>
<link>2345</link>
<link>5678</link>
</links>
</document>
And the same as json:
{
id: "1234",
content: "This is document that I posted...",
author: "Michał Białecki",
links: {
link: ["1234", "5678"]
}
}
And that’s it! Sending the same document either in XML or Json to api/documents/SendDocument endpoint just work. Only remember about correct Content-Type header in your request.
You can read the whole post at my blog: http://www.michalbialecki.com/2018/04/25/accept-xml-request-in-asp-net-mvc-controller/
with core 2, you need to specifically add the options to the mvc serverice to enable xml input/output:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(options =>
{
options.InputFormatters.Add(new XmlSerializerInputFormatter());
options.OutputFormatters.Add(new XmlSerializerOutputFormatter());
});
}
and then change the Accept header to:
application/xml
or
application/json