web-dev-qa-db-fra.com

WCF REST Service JSON Post data

Vous cherchez des conseils sur un service de repos wcf 4 qui est basé sur l'extension WCF REST Template 40 (CS) dans VS2010. J'ai passé les derniers jours à essayer d'obtenir ce bugger pour travailler, passer en revue d'autres articles, et même si je me suis approché, je n'arrive pas à franchir la ligne d'arrivée. Après beaucoup de frustration, il arrive enfin de frapper le service et de publier (en utilisant le générateur de demandes de violoneux), mais le paramètre de méthode apparaît comme nulle, mais elle est définie correctement dans le générateur de demandes. Je suppose que cela peut être un problème de configuration à ce stade, mais à mesure que la date limite approche, je manque de temps pour plus de recherches. FWIW, dans le débogage, la variable jsonstring est nulle. En soi, c'est une sorte de question noob car c'est la première fois par REST pour moi, toute aide serait très appréciée!

Merci d'avance.

web.config

<system.web>
  '<compilation debug="true" targetFramework="4.0" />
</system.web>

<system.webServer>
 <modules runAllManagedModulesForAllRequests="true">
   <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
 </modules>
</system.webServer>

<system.serviceModel>
 <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
 <standardEndpoints>
   <webHttpEndpoint>
     <standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true"/>
   </webHttpEndpoint>
 </standardEndpoints>
</system.serviceModel>

global.asax.cs

   public class Global : HttpApplication
  {
      void Application_Start(object sender, EventArgs e)
      {
         RegisterRoutes();
      }

      private void RegisterRoutes()
      {
         RouteTable.Routes.Add(new ServiceRoute("Scoring", new WebServiceHostFactory(), typeof(ScoringSvc)));
      }
   }

Code de service

[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class ScoringSvc 
{
   [OperationContract]
   [WebInvoke
      (Method = "POST",
      BodyStyle = WebMessageBodyStyle.WrappedRequest,
      RequestFormat=WebMessageFormat.Json,
      ResponseFormat=WebMessageFormat.Json)]
   public string BOB(string jsonstring)
   {
      return "Received: " + jsonstring;
   }
}

En-tête de demande Fiddler

Host: localhost
Content-Length: 20
Content-Type: application/json; charset=UTF-8

corps de la demande

{"Name":"Frank"}

Réponse brute du violoneux

HTTP/1.1 200 OK
Cache-Control: private
Content-Length: 12
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Mon, 21 Mar 2011 21:31:14 GMT

"Received: "
11
Grogh

Je suis tombé sur ce lien WCF + REST: où sont les données de la demande? et j'ai vu la réponse de Glenn pour passer un flux à la méthode, puis déchirer cela avec un lecteur de flux dans une chaîne pour obtenir les données de publication du formulaire.

Modification du code de service prototype comme suit

[OperationContract]
[WebInvoke
   (UriTemplate="/BOB",
    Method = "POST",
    BodyStyle = WebMessageBodyStyle.WrappedRequest)]
public string BOB (Stream streamdata)
{
    StreamReader reader = new StreamReader(streamdata);
    string res = reader.ReadToEnd();
    reader.Close();
    reader.Dispose();
    return "Received: " + res;
}

Et cela semble faire l'affaire, le tableau json complet est passé dans le flux, lu dans la chaîne locale, et je peux ensuite l'attaquer en utilisant json.net pour sérialiser dans/à partir d'un dictionnaire pour passer à la logique métier. Pas vraiment joli, mais fonctionnel.

20
Grogh

J'utilise celui-ci et fonctionne:

[WebInvoke(ResponseFormat = WebMessageFormat.Json, 
           RequestFormat = WebMessageFormat.Json,
           BodyStyle = WebMessageBodyStyle.WrappedRequest,
           Method = "POST",
           UriTemplate = "setExpositions?shelfId={shelfId}")]
[OperationContract]
public bool SetExpositions(int shelfId, List<WcfExposition> expositions)
{
}

où clayId est passé dans GET et les expositions sont passées dans le corps du message en tant que données JSON.

3
Christian

Avez-vous essayé d'entrer {"jsonstring": "Frank"} dans le corps de la demande (dans le générateur de demandes du violoneux)?

2
Lei Shi

Je pense qu'il peut y avoir un problème dans BodyStyle = WebMessageBodyStyle.WrappedRequest, qui - je pense, bien que la documentation ne soit pas claire - s'attend à ce que l'élément soit enveloppé avec le nom de la méthode.

Définissez celui qui n'est pas encapsulé et définissez le corps de la demande sur '{"Name":"Frank"}' (remarquez les guillemets simples qui l'entourent. Ce que vous publiez en fait une chaîne contenant JSON. Je ne sais pas pourquoi vous voudriez cela. Cela me rappelle http://thedailywtf.com/Articles/XMLd- XML.aspx où ils mettent xml dans leur xml. Vous mettez JSON dans votre JSON.

0
Martijn