I'm trying to post XML to asp.net core 2:
$.ajax({
type: "POST",
url: 'api/Test',
data: "<test>hello<test>",
contentType: "application/xml",
success: function (response) { alert(response); },
});
How should I write the action, so it accepts the xml as parameter?
IActionResult Post([FromBody]string xml)
-> xml is nullIActionResult Post([FromBody]XElement xml)
-> xml is nullIActionResult Post(XElement xml)
->
InvalidOperationException: Could not create an instance of type 'System.Xml.Linq.XElement'. Model bound complex types must not be abstract or value types and must have a parameterless constructor.IActionResult Post(string xml)
-> xml is nullin the Startup.ConfigureServices:
services.AddMvc()
.AddXmlSerializerFormatters();
How to write the controller so that it accepts XML as a parameter? I know I can read it from HttpContext.Request, but I want it to be parameter
I've ended up creating custom InputFormatter, which was pretty straitforward, but if there is better alternative, you are very welcome to write an answer!
public class XDocumentInputFormatter : InputFormatter, IInputFormatter, IApiRequestFormatMetadataProvider
{
public XDocumentInputFormatter()
{
SupportedMediaTypes.Add("application/xml");
}
protected override bool CanReadType(Type type)
{
if (type.IsAssignableFrom(typeof(XDocument))) return true;
return base.CanReadType(type);
}
public override async Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context)
{
var xmlDoc = await XDocument.LoadAsync(context.HttpContext.Request.Body, LoadOptions.None, CancellationToken.None);
return InputFormatterResult.Success(xmlDoc);
}
}
Register the XDocumentInputFormatter in startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(options => options.InputFormatters.Insert(0, new XDocumentInputFormatter()));
}
Just a change for the answer given by Liero, you should use a StreamReader, so you can support multiple encodings. Tested my solution with UTF-8, UTF-16 and ASCI declaration header.
Change the Method from XDocumentInputFormatter:
public override async Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context)
{
var xmlDoc = await XDocument.LoadAsync(context.HttpContext.Request.Body, LoadOptions.None, CancellationToken.None);
return InputFormatterResult.Success(xmlDoc);
}
To below
public override async Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context) {
// Use StreamReader to convert any encoding to UTF-16 (default C# and sql Server).
using (var streamReader = new StreamReader(context.HttpContext.Request.Body)) {
var xmlDoc = await XDocument.LoadAsync(streamReader, LoadOptions.None, CancellationToken.None);
return InputFormatterResult.Success(xmlDoc);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With