Как установить Json.Net в качестве сериализатора по умолчанию для службы WCF REST
Можно ли переопределить поведение WCF DataContractSerializer по умолчанию, когда Serialize/DeSerialize сущности и вместо этого использовать JSON.NET?
У меня есть следующий контракт на обслуживание объекта City. По соображениям дизайна объект City имеет IsReference = true, поэтому по умолчанию DataContractSerializer вызывает ошибки.
Для методов "GET" я могу справиться с ситуацией с JsonConvert.DeserializeObject, но с методами "PUT, POST, DELETE" DataContractSerializer имеет приоритет и терпит неудачу, поскольку объекты IsReference не могут быть сериализованы.
Я нашел эту Post, чтобы реализовать IOperationBehavior и предоставить собственный Serializer, но я не знаю, как интегрировать Json.NET с этим. и я считаю, что для этого должен быть более прямой подход.
Id ценит любую помощь или рекомендации относительно этого сценария или советы другим подходам.
[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class CityService
{
[Description("Get all Cities")]
[WebGet(UriTemplate = "")]
public Message Cities()
{
}
[Description("Allows the details of a single City to be updated.")]
[WebInvoke(UriTemplate = "{code}", Method = "PUT")]
public Message UpdateCity(string code, City city)
{
}
}
Большое спасибо
Хоссама
Ответы
Ответ 1
Использование расширенных кодеров и сериализаторов (см. http://msdn.microsoft.com/en-us/library/ms733092.aspx) или другие методы расширения WCF, такие как использование DataContractSerializerOperationBehavior
, очень интересно, но для вашей особой проблемы есть более простые способы решения.
Если вы уже используете тип Message
, чтобы возвращать результаты, используйте WCF4, вы можете сделать что-то вроде следующего:
public Message UpdateCity(string code, City city)
{
MyResponseDataClass message = CreateMyResponse();
// use JSON.NET to serialize the response data
string myResponseBody = JsonConvert.Serialize(message);
return WebOperationContext.Current.CreateTextResponse (myResponseBody,
"application/json; charset=utf-8",
Encoding.UTF8);
}
В случае ошибок (например, HttpStatusCode.Unauthorized
или HttpStatusCode.Conflict
) или в других ситуациях, когда вам нужно установить код состояния HTTP (например, HttpStatusCode.Created
), вы можете продолжать использовать WebOperationContext.Current.OutgoingResponse.StatusCode
.
В качестве альтернативы вы также можете вернуть Stream
(см. http://blogs.msdn.com/b/carlosfigueira/archive/2008/04/17/wcf-raw-programming-model-web.aspx и http://msdn.microsoft.com/en-us/library/ms732038.aspx) вместо Message
, чтобы возвращать любые данные без дополнительной обработки по умолчанию с помощью сериализатора Microsoft JSON. В случае WCF4 вы можете использовать CreateStreamResponse
(см. http://msdn.microsoft.com/en-us/library/dd782273.aspx) вместо CreateTextResponse
. Не забудьте установить позицию потока в 0 после записи в потоке, если вы будете использовать эту технику для получения ответа.
Ответ 2
Есть ли какая-то причина, по которой вы хотите использовать библиотеку Json.NET. Если вы хотите вернуть JSON, почему бы просто не использовать свойство ResponseFormat из атрибутов WebGet и WebInvoke?
[WebGet(UriTemplate = "", ResponseFormat = WebMessageFormat.Json)]
Это должно быть в большинстве случаев. Какую версию WCF вы используете? Любая причина, по которой вы возвращаете тип сообщения, а не фактический тип?