How to Add a custom InputFormatter in ASP.NET Core
By FoxLearn 2/10/2025 7:44:04 AM 50
If you need a custom InputFormatter that processes application/xml
requests. This formatter will convert the XML data into a MyModel
object.
Steps:
- Subclass the
InputFormatter
class. - Specify the Content-Type the formatter will handle (e.g.,
application/xml
). - Deserialize the request body into the model.
- Register the formatter in the application's services.
Custom InputFormatter
For example:
using Microsoft.AspNetCore.Mvc.Formatters; using System.IO; using System.Text; using System.Threading.Tasks; using System.Xml.Serialization; public class XmlModelInputFormatter : InputFormatter { public XmlModelInputFormatter() { // Specify the Content-Type(s) this InputFormatter can handle SupportedMediaTypes.Add("application/xml"); } public override async Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context) { using (var reader = new StreamReader(context.HttpContext.Request.Body, Encoding.UTF8)) { var xmlContent = await reader.ReadToEndAsync(); // Deserialize the XML into your model (assumes MyModel is your target model) var serializer = new XmlSerializer(typeof(MyModel)); using (var stringReader = new StringReader(xmlContent)) { var result = (MyModel)serializer.Deserialize(stringReader); return InputFormatterResult.Success(result); } } } protected override bool CanReadType(Type type) { // Specify the model type this InputFormatter can handle return type == typeof(MyModel); } }
Register the Formatter
In the Program.cs
or Startup.cs
, add the custom input formatter to the application's services:
var builder = WebApplication.CreateBuilder(args); // Add custom InputFormatter to the service collection builder.Services.AddControllers(options => { options.InputFormatters.Add(new XmlModelInputFormatter()); }); var app = builder.Build(); app.MapControllers(); app.Run();
Use the Formatter in a Controller
[HttpPost()] [Consumes("application/xml")] // Only accept XML Content-Type for this action public IActionResult Post([FromBody] MyModel model) { return Ok($"Received model with Id: {model.Id} and Name: {model.Name}"); }
You can test this functionality by sending the following XML request to your API endpoint (e.g., /api/my-model
):
POST /api/my-model
Content-Type: application/xml
<MyModel> <Id>123</Id> <Name>Test Model</Name> </MyModel>
Response:
If the deserialization is successful, you would receive an OK response with a message like:
Received model with Id: 123 and Name: Test Model
Handling Errors:
To handle errors during deserialization, you can modify the formatter to check for invalid XML and add custom error messages:
public override async Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context) { try { using (var reader = new StreamReader(context.HttpContext.Request.Body, Encoding.UTF8)) { var xmlContent = await reader.ReadToEndAsync(); var serializer = new XmlSerializer(typeof(MyModel)); using (var stringReader = new StringReader(xmlContent)) { var result = (MyModel)serializer.Deserialize(stringReader); return InputFormatterResult.Success(result); } } } catch (Exception ex) { context.ModelState.TryAddModelError("Body", "Invalid XML format."); return InputFormatterResult.Failure(); } }
If the XML is invalid, the API would return a 400 Bad Request response with error details:
{ "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1", "title": "One or more validation errors occurred.", "status": 400, "traceId": "some-trace-id", "errors": { "Body": [ "Invalid XML format." ] } }
This way, you can customize how your API deserializes requests and provide better error handling for non-standard content types like application/xml
.
- Basic Authentication in ASP.NET Core
- How to Implement Stripe Payment Gateway in ASP.NET Core
- Comparing ASP.NET SOAP Services and Core APIs
- How to fix System.InvalidOperationException: Scheme already exists: Identity.Application
- Two-Factor Authentication with Google Authenticator in ASP.NET Core
- Implementing Passkeys to ASP.NET Core Application
- How to Implement Passkey Authentication in ASP.NET Core
- Implementing Google Authentication in the Blazor WebAssembly App