4

I have a simple Web API controller with a POST method, that accepts an object. When the clients posts data as JSON the API works fine. Even when data is sent as XML with encoding="utf-8", the model binds seamlessly (I have added the following line in WebApiConfig to use Xml Serialization instead of DataContract)

config.Formatters.XmlFormatter.UseXmlSerializer = true;

Below is my ApiController:

public class InfoController : ApiController
{
    public HttpResponseMessage Post(InfoRequest infoRequest)
    {
        //do work and return something
        return Request.CreateResponse(HttpStatusCode.Accepted, infoRequest != null);
    }
}

With the types

public class InfoRequest
{
    public string Id { get; set; }
    public int Total { get; set; }
    public Status Status { get; set; }
}

public enum Status
{
    None = 0,
    Confirmed,
    Cancelled
}

Now when client makes request following set of data, it works fine

Content-Type: application/json
body:
{
    "Id": "ACARG021",
    "Total": 20,
    "Status": "Confirmed"
}

This works fine, as well

Content-Type: application/xml
body:
<?xml version="1.0" encoding="utf-8"?>
<InfoRequest>
    <Id>ACARG021</Id>
    <Total>20</Total>
    <Status>Confirmed</Status>
</InfoRequest>

But, when a XML is posted with UTF-16 the model binding fails and the controller method gets null passed to it.

Content-Type: application/xml; charset=utf-16
//Accept-Charset: utf-16 //Edit: wrong header, removed
body:
<?xml version="1.0" encoding="utf-16"?>
<InfoRequest>
    <Id>ACARG021</Id>
    <Total>20</Total>
    <Status>Confirmed</Status>
</InfoRequest>

As suggested in some other SO posts, adding this to the WebApiConfig doesn't help

Encoding utf16 = Encoding.GetEncoding("utf-16");
config.Formatters.XmlFormatter.SupportedEncodings.Add(utf16);
Arghya C
  • 9,805
  • 2
  • 47
  • 66
  • Have you tried resetting the default json encodings as well? See https://blogs.msdn.microsoft.com/henrikn/2012/04/22/asp-net-web-api-content-negotiation-and-accept-charset/ – Stinky Towel Oct 07 '16 at 15:03
  • Having the same issue in dotnet core model binding. any encoding other than utf-8 doesnt work. I modified the xmlformatter too. No luck. Let me know if you found an answer on this one, even the the question is ancient by now. – Pezetter Sep 23 '20 at 04:03

1 Answers1

0

On server side this should work out of the box. So I guess problem will be your POST. Content type header should have correct encoding. It is not enough to change header in XML itself to encoding="utf-16". Try:

Content-Type: application/xml; charset=utf-16

You also need to actually send data in that encoding not just change the header.

Honza
  • 335
  • 3
  • 14
  • Thanks for the answer. But, mentioning charset in header doesn't help much. Web API still cannot decode it. – Arghya C Oct 10 '16 at 07:10
  • Can you show how you do the POST? Are you sure you can't change it to UTF-8? UTF-16 will require double amount of data to be transferred over TCP/IP. – Honza Oct 10 '16 at 13:46
  • As of now (for testing) I'm posting using Postman client with exactly the same data/headers I've mentioned in the question. And I'm owning the service here, not the client. `UTF-16` is some specific requirement of the client, so cannot change that. I know it increases the data size, but need to get that working for now. – Arghya C Oct 12 '16 at 11:34
  • Are you sure that you sending UTF-16 data from Postman using binary mode? It is not enough to set Content-Type header in Postman. If header says UTF-16, but data are UTF-8 encoded it will result in infoRequest null. You can try swap `Post(InfoRequest infoRequest)` for `Post(HttpRequestMessage request)` and then see `request.Content.ReadAsByteArrayAsync().Result`. – Honza Oct 12 '16 at 23:44