У меня есть объект json, который я сериализую и публикую. Я обнаружил, что если один из членов строки моего json-объекта имеет несколько символов Unicode, таких как é, ó, 6̄ (у меня есть некоторые другие символы Unicode, которые не возвращают ошибку HTTP 400), что запрос возвращает HTTP 400 Плохой запрос.Кодировка символов заставляет мой запрос ASP Web API терпеть неудачу с HTTP 400: Bad Request
Вот упрощенный код, как вызов был сделан:
WebClient client;
Foo myObject = new Foo();
myObject.StringField1 = "é";
string serializedObjects = Newtonsoft.Json.JsonConvert.SerializeObject(myObject)
client.Headers[HttpRequestHeader.ContentType] = "application/json;charset=utf-8";
var response = client.UploadString(url, serializedObjects);
Вот код, как позвонивших принимается на стороне сервера:
public async Task<IHttpActionResult> Post([FromBody] IList<Foo> myObjects){}
Вот некоторые вещи что я исследовал/пытался и некоторые допущения, которые я сделал:
1) Получить строковый объект как байты UTF8, а затем преобразовать его обратно в строку
Encoding.UTF8.GetString(Encoding.UTF8.GetBytes(serializedObjects))
2) Когда я делаю запрос и фиксирую трафик с помощью Fiddler и проверяю запрос в Raw. Для символов Unicode, которые не возвращают ошибку 400, они заменяются символом '?' однако для тех, которые вызывают 400, они отображаются в виде пробела. Однако, когда я смотрю на просмотр JSON, он отображается как нулевой символ « »
3) Возврат HTTP 400: ASP Web API не может десериализовать объект правильно, поэтому я попытался использовать библиотеку Newtonsoft для сериализации и десериализации объекта и это работает отлично. (По умолчанию сериализатора для ASP Web API является JSON.NET поэтому она должна быть выполнением тех же сериализаций http://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization)
string b = JsonConvert.SerializeObject(a);
Foo c = (Foo) JsonConvert.DeserializeObject(b, typeof(Foo));
// And I tried deserializing using the generic method
Foo d = JsonConvert.DeserializeObject<Foo>(b);
4) Я был убежден, что это была проблема с моим сервером отвергая эти специальные символы, но когда я использовал Fiddler для повторного запроса (вставка обратно в место, где Fiddler удалил его в исходном запросе), вызов преуспевает. 5) Я подтвердил свой Content-Type на http://www.iana.org/assignments/media-types/media-types.xhtml, а также явно указал кодировку utf8.
Таким образом, мне кажется, что это проблема с кодировкой, но é должен быть допустимым символом UTF-8. Я проверил его в виджетах Unicode Explorer Джона Скита на своей странице. Поэтому у меня нет идей, почему это вызывает проблемы ...
BTW вот страница с инструментом, который я использовал для поиска юникода для é [link] (http://csharpindepth.com/Articles/General/Unicode.aspx), который также имел отличную информацию о Unicode вообще также! – Keith
Вы уверены, что 'client' использует UTF-8 для кодирования этих строк? Я думаю, что у него есть поле «Кодирование», каково значение этого поля? – roeland
Вы установили ['client.Encoding = Encoding.UTF8;'] (https://msdn.microsoft.com/en-us/library/system.net.webclient.encoding%28v=vs.110%29.aspx)? – dbc