Как установить Json.Net в качестве сериализатора по умолчанию для службы WCF REST - PullRequest
21 голосов
/ 25 июня 2010

Можно ли переопределить стандартное поведение WCF DataContractSerializer, когда объекты Serialize / DeSerialize, и вместо этого использовать JSON.NET?

У меня есть следующий контракт на обслуживание для обработки объекта City.Из соображений дизайна у объекта City есть IsReference = true, и поэтому DataContractSerializer по умолчанию выдает ошибки.

Для методов «GET» я могу обработать ситуацию с JsonConvert.DeserializeObject, но с «PUT, POST, DELETE»методы DataContractSerializer имеют приоритет и не могут жаловаться на сущности IsReference, которые нельзя сериализовать.

Я нашел эту публикацию , чтобы реализовать IOperationBehavior и предоставить свой собственный Serializer, но я не знаю, как интегрировать Json.NET с этим.и я считаю, что для этого должен быть более прямой подход.

Буду признателен за любую помощь или руководство в отношении этого сценария или советы по другим подходам.

[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)
    {
    }
}

Большое спасибо

Хоссам

Ответы [ 3 ]

21 голосов
/ 28 июня 2010

Использование расширенных кодировщиков и сериализаторов (см. 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 после записи в поток, если вы будете использовать эту технику для получения ответа.

1 голос
/ 26 июня 2010

Есть ли какая-то причина, по которой вы хотите использовать библиотеку Json.NET специально. Если вы хотите вернуть JSON, почему бы просто не использовать свойство ResponseFormat из атрибутов WebGet и WebInvoke?

[WebGet(UriTemplate = "", ResponseFormat = WebMessageFormat.Json)]

Это должно быть в большинстве случаев. Какую версию WCF вы используете? По какой причине вы возвращаете тип сообщения, а не фактический тип?

0 голосов
/ 05 февраля 2018

Определите его в веб-конфигурации службы для поведения службы:

<endpointBehaviors>
   <behavior name="restfulBehavior">
      <webHttp defaultOutgoingResponseFormat="Json" defaultBodyStyle="Wrapped" automaticFormatSelectionEnabled="False" />
      <!--<enableWebScript />-->
   </behavior>
</endpointBehaviors>

или в контракте на работу вашего интерфейса

[OperationContract]
[WebInvoke(Method = "GET", 
           UriTemplate = "/advertisements/{app_id}/{access_token}/{genero}/{age}", 
           ResponseFormat = WebMessageFormat.Json,
           RequestFormat = WebMessageFormat.Json, 
           BodyStyle = WebMessageBodyStyle.Wrapped)]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...