Я наконец-то нашел решение для этого.Это не то, что я бы предпочел (который должен был бы возвращать определенный тип объекта и каким-то образом инструктировать WCF использовать сериализатор Json.Net вместо DataContractJsonSerializer), но он работает отлично, и это просто и понятно.
Расширение моего надуманного примера с использованием этого нового решения:
[WebGet(UriTemplate = "hello")]
public void SayHello()
{
SimpleMessage message = new SimpleMessage() {Message = "Hello World"};
string json = JsonConvert.Serialize(message);
HttpContext.Current.Response.ContentType = "application/json; charset=utf-8";
HttpContext.Current.Response.Write(json);
}
Обратите внимание на тип возврата void
.Мы ничего не возвращаем, так как это будет сериализовано с DataContractJsonSerializer.Вместо этого я пишу прямо в поток вывода ответа.Так как тип возвращаемого значения void, конвейер обработки не устанавливает тип содержимого в тип по умолчанию "application / json", поэтому я установил его явно.
, поскольку при этом используется HttpContext
, I 'Я предполагаю, что это будет работать, только если у вас есть [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
в вашем классе обслуживания, так как это заставит запросы к службе проходить через конвейер ASP.NET.Без совместимости с asp.net HttpContext не будет доступен, поскольку предполагается, что хостинг wcf не зависит от хоста.
При использовании этого метода результаты выглядят идеально в firebug для запросов GET.Правильный тип контента, правильная длина контента и необработанный json, без кавычек.И я получаю сериализацию, которую я хочу, используя Json.Net.Лучшее из двух миров.
Я не на 100% уверен в том, с какими препятствиями я могу столкнуться при сериализации de , когда мои методы обслуживания имеют в качестве входных параметров типы объектов [DataContract].Я предполагаю, что DataContractJsonSerializer будет использоваться для этого тоже.Перейду тот мост, когда я приду к нему ... если это создаст проблему.Пока нет, с моими простыми DTO.
ОБНОВЛЕНИЕ См. Ответ Олега (часть ОБНОВЛЕНИЕ2).Он меняет тип возвращаемого значения метода обслуживания с void на System.ServiceModel.Channels.Message
, и вместо использования HttpContext.Current.Response.Write()
он использует:
return WebOperationContext.Current.CreateTextResponse (json,
"application/json; charset=utf-8", Encoding.UTF8);
, что действительно является лучшим решением.Спасибо, Олег.
ОБНОВЛЕНИЕ 2 Есть еще один способ сделать это.Измените тип возврата вашего сервиса с Message на Stream и верните это:
WebOperationContext.Current.OutgoingResponse.ContentType = "application/json; charset=utf-8";
return new MemoryStream(System.Text.Encoding.UTF8.GetBytes(json));
Я не проводил никаких специальных тестов, но возможно, что это был бы лучший выбор для методов, которые потенциально могут возвращать большие суммыданных.Я не знаю, имеет ли это значение для недвоичных данных, хотя.Во всяком случае, мысль.