Como criar JSON para corresponder / serializar para DataContract no WCF Rest Service

Interface:

namespace SQRT_WCF
    {
    [DataContract]
    public class PlaceOrder
    {
        [DataMember]
        public string claimID { get; set; }
        [DataMember]
        public string rederenceDate { get; set; }
    }
}

Método C # invocado:

public SQ_jsonModel.Response placeOrder(PlaceOrder argPlaceOrderJSON)
{
   ...
}

Anexei meu serviço da web aos processos de trabalho e rastreei o código. Até agora, tudo o que tentei, a variável argPlaceOrderJSON é nula.

Eu tentei pelo menos três variações:

Variação # 1

{
         "claimID" : "value",
         "rederenceDate" : "value"
}

Variação 2:

{
    "PlaceOrder" : {
         "claimID" : "value",
         "rederenceDate" : "value"
}

Variação # 3:

{
    "ns0:PlaceOrder" : {
        "@xmlns:ns0" : "SQRT_WCF",
         "claimID" : "value",
        "rederenceDate" : "value"
}

Eu escrevi um rápido programa de console em C # para criar e serializar um objeto e ele corresponde à variação 1 acima. Então agora estou pensando que o problema não é o JSON, mas algo com o aperto de mão entre a SOAP-UI e o serviço da web. Vou escrever um cliente de teste C # ao lado para ver o que acontece lá.

SQRT_WCF.PlaceOrder order = new SQRT_WCF.PlaceOrder();
order.ClaimID = "claim1"; 
string strJson = new JavaScriptSerializer().Serialize(order);

Alguém pediu atributos no serviço da web, assumindo que era isso que ele queria dizer:

interface pública ISQRTREST {[OperationContract] void DoWork ();

    [OperationContract]
    [WebInvoke(Method="GET",
        ResponseFormat = WebMessageFormat.Json ,
        BodyStyle = WebMessageBodyStyle.Wrapped ,
        UriTemplate ="json/{id}"
        )]
    string JSONData(String id);


    [OperationContract]
    [WebInvoke(Method = "POST",
        ResponseFormat = WebMessageFormat.Json,
        BodyStyle = WebMessageBodyStyle.Wrapped,
        UriTemplate = "placeOrder/"
        )]
    SQ_jsonModel.Response placeOrder(PlaceOrder order);

}

Web.Config

<?xml version="1.0"?>
<configuration>

  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <services>
      <service name="SQRT_WCF.SQRTREST" behaviorConfiguration="ServiceBehaviour">
        <endpoint address="" binding="webHttpBinding" bindingConfiguration="longTimeoutBinding" contract="SQRT_WCF.ISQRTREST" behaviorConfiguration="web">
        </endpoint>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehaviour">
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="web">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <bindings>
      <webHttpBinding>
        <binding name="longTimeoutBinding"
        receiveTimeout="00:10:00" sendTimeout="00:10:00">
          <security mode="None"/>
        </binding>
      </webHttpBinding>
    </bindings>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>

</configuration>

UPDATE: Parece que mudar BodyStyle = WebMessageBodyStyle.Bare conseguiu trabalhar com a variação 1.

Mas agora, o problema é que eu preciso fazê-lo funcionar com o WebMessageBodyStyle.Wrapped.

Este é um serviço da web existente que está em produção. A pessoa que escreveu o programa já se foi há muito tempo e agora a equipe B2B / BizTalk está assumindo o projeto. Estamos usando o BT2010, que ainda não possui REST, e estamos tentando fornecer a mesma interface para nossos clientes, para que eles não precisem alterar nada além do URL.

Formato do corpo do serviço da web RESTful parece explicar bastante bem, estou prestes a experimentar a variação 2 com a opção .wrapped em C #.

Atualização 2: A tentativa da variação 2 com BodyWrapped ainda está recebendo um objeto nulo:

Foi assim que eu o envolvi. Tomou o que funcionou na Atualização1

string strPostBodyWrapped = "{\"PlaceOrder\" : " + strPostBody + "}";

Fará mais depuração após o almoço.

Atualização 3: Ainda sem sorte. Baseado no StackOverflow ref acima, parece que o wrapper deve ser "entidade", que tentei de várias maneiras:

Na SOAP-UI:

{
    "entity" : { 
        "claimID" : "value",
}

Eu também tentei "Entidade" em vez de "entidade", apenas tenha certeza.

Todos os campos no meu DataContract são string, portanto, não deve haver problema em serializar datas ou números.

No programa testador do C # Client:

            strPostBody = replaceSingleWithDoubleQuotes("{'ClaimID':'testvalue'}"); 

            string strPostBodyWrapped = replaceSingleWithDoubleQuotes("{'entity': ") + strPostBody + "}";

public static string replaceSingleWithDoubleQuotes(string argText)
    {
        return argText.Replace("'", "\"");
    }

Se eu tentar algo ruim em SOAP_UI, assim:

{
    "entity" : {  xxx 
        "claimID" : "value",
}

Então percebi que entidade não era uma palavra-chave, mas o nome da classe dele ... oops. Então, eu tentei "Placeorder" e "placeorder" como meu invólucro para o meu caso.

Eu recebo um erro agradável como este:

The server encountered an error processing the request. The exception message is 'The formatter threw an exception while trying to deserialize the message: Error in deserializing body of request message for operation 'placeOrderSQRT'. Encountered unexpected character 'x'.'...

Portanto, não entendo por que, neste caso, o analisador falha, mas em outros casos não falha, mas também não define nenhum valor de campo.

Se eu tentar nomes de campos inválidos, mas com sintaxe correta, o analisador parece não apresentar nenhum erro, por exemplo "claimIDxxxxxxxx": "value"

questionAnswers(3)

yourAnswerToTheQuestion