2012-07-16 3 views
3

Je crée un service de repos WCF pour télécharger des images à partir d'une application mobile. mais je reçois Le serveur distant a renvoyé une erreur: (400) Mauvaise demande. quelqu'un peut-il me signaler ce que j'ai fait de mal? Voici mes définitions:Impossible de télécharger l'image vers le service de repos WCF

[OperationContract] 
    [WebInvoke(BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "/PostImage",Method ="POST")] 

PublicMessage PostImage(Upload obj); 

[DataContract] 
    public class Upload 
    { 
     [DataMember] 
     public Stream File { get; set; } 
    } 

Définition du service:

public PublicMessage PostImage(Upload obj) 
    { 
     byte[] buffer = StreamToByte(obj.File); //Function to convert the stream to byte array 
    FileStream fs = new FileStream(@"D:\ShopMonkeyApp\Desert.jpg", FileMode.Create, FileAccess.ReadWrite); 
     BinaryWriter bw = new BinaryWriter(fs); 

     bw.Write(buffer); 

     bw.Close(); 

     return new PublicMessage { Message = "Recieved the image on server" }; 
    } 

Client Application:

string filePath = @"D:\ShopMonkeyApp\Desert.jpg"; 

     string url = "http://localhost:50268/shopmonkey.svc/PostImage/"; // Service Hosted in IIS 

     HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); 

     request.Accept = "text/xml"; 

     request.Method = "POST"; 

     request.ContentType = "image/jpeg"; 

     using (Stream fileStream = File.OpenRead(filePath)) 

     using (Stream requestStream = request.GetRequestStream()) 
     { 

      int bufferSize = 1024; 

      byte[] buffer = new byte[bufferSize]; 

      int byteCount = 0; 

      while ((byteCount = fileStream.Read(buffer, 0, bufferSize)) > 0) 
      { 

       requestStream.Write(buffer, 0, byteCount); 

      } 

     } 

     string result; 

     using (WebResponse response = request.GetResponse()) 

     using (StreamReader reader = new StreamReader(response.GetResponseStream())) 
     { 

      result = reader.ReadToEnd(); 

     } 

     Console.WriteLine(result); 

Config Web:

<system.serviceModel> 
     <services> 
     <service name="ShopMonkey.ShopMonkey" behaviorConfiguration="ServiceBehaviour"> 
     <!-- Service Endpoints --> 
     <!-- Unless fully qualified, address is relative to base address supplied above --> 
     <endpoint address ="" binding="webHttpBinding" contract="ShopMonkey.IShopMonkey" behaviorConfiguration="web"> 
      <!-- 
       Upon deployment, the following identity element should be removed or replaced to reflect the 
       identity under which the deployed service runs. If removed, WCF will infer an appropriate identity 
       automatically.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/> 
      <dataContractSerializer maxItemsInObjectGraph="10000000"/> 
     </behavior> 
     </endpointBehaviors> 
    </behaviors> 
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" /> 
    </system.serviceModel> 
    <system.webServer> 
    <modules runAllManagedModulesForAllRequests="true"/> 
    </system.webServer> 

Merci

Vijay

+0

également s'il vous plaît nettoyer vos échantillons de code - indentation est très mauvais et il y a des erreurs évidentes C# dans le code client qui l'empêchera la compilation dans l'état actuel. –

+0

Essayez de supprimer le style de corps et de voir si cela fonctionne. De plus, veuillez nous indiquer à quoi ressemble votre méthode StreamToByte? – Rajesh

+0

J'ai mis à jour ma réponse avec un exemple de code. Désolé pour le retard. – Rajesh

Répondre

0

Si vous n'avez pas d'autres propriétés sur la classe Télécharger puis changer la méthode de service WCF d'avoir un param Stream plutôt que de l'envelopper dans une classe comme ci-dessous:

[OperationContract] 
[WebInvoke(UriTemplate = "/PostImage",Method ="POST")] 
PublicMessage PostImage(Stream obj); 

Ensuite, vous peut utiliser la classe WebClient pour télécharger un fichier directement comme indiqué ci-dessous:

var c = new System.Net.WebClient(); 
c.OpenWrite(string.Concat("http://localhost:50268/shopmonkey.svc", "/PostImage"), "POST"); 
c.Headers[HttpRequestHeader.ContentType] = "image/jpeg";    
return c.UploadFile(string.Concat(serviceBaseUrl, resourceUrl), filePath); 

Se référer également à ce link.

MISE À JOUR:

S'il vous plaît trouver l'échantillon pour obtenir votre code de travail ci-dessous:

[OperationContract] 
[WebInvoke(UriTemplate = "/PostImage",Method ="POST")] 
PublicMessage PostImage(Upload obj); 

[DataContract] 
public class Upload 
{ 
    [DataMember] 
    public MemoryStream FileContent { get; set; } 
} 

Maintenant, votre méthode qui implémente l'Postimage se présente comme suit:

public PublicMessage PostImage(Upload obj) 
{ 
     byte[] buffer = new byte[obj.FileContent.Length]; 
     using (FileStream ms = new FileStream(@"D:\ShopMonkeyApp\Temp\Desert.jpg", FileMode.OpenOrCreate)) 
     { 
      obj.FileContent.Position = 0; 
      int read = fileInfo.Content.Read(buffer, 0, buffer.Length); 
      ms.Write(buffer, 0, read); 
     } 

    return new PublicMessage { Message = "Recieved the image on server" }; 
} 

maintenant depuis notre code côté serveur est maintenant déplacé vers la partie côté client qui télécharge votre fichier sur le serveur comme ci-dessous:

private string ClientSample() 
    { 
      var uploadObject = new Upload(); 
      Image image = Image.FromFile(@"D:\ShopMonkeyApp\Desert.jpg"); 
      MemoryStream ms = new MemoryStream(); 
      uploadObject.FileContent = new MemoryStream(); 
      image.Save(ms, System.Drawing.Imaging.ImageFormat.Png); 
      ms.WriteTo(uploadObject.FileContent); 
      ms.Close(); 

     string responseMessage = null;    
     var request = WebRequest.Create(http://localhost:50268/shopmonkey.svc/PostImage) as HttpWebRequest; 
     if (request != null) 
     { 
      request.ContentType = "application/xml"; 
      request.Method = method; 
     } 

     if(method == "POST" && requestBody != null) 
     { 
      byte[] requestBodyBytes; 
      requestBodyBytes = ToByteArrayUsingDataContractSer<Upload>(requestBody); 
      request.ContentLength = requestBodyBytes.Length; 
      using (Stream postStream = request.GetRequestStream()) 
       postStream.Write(requestBodyBytes, 0, requestBodyBytes.Length);      
     } 

     if (request != null) 
     { 
      var response = request.GetResponse() as HttpWebResponse; 
      if(response.StatusCode == HttpStatusCode.OK) 
      { 
       Stream responseStream = response.GetResponseStream(); 
       if (responseStream != null) 
       { 
        var reader = new StreamReader(responseStream); 

        responseMessage = reader.ReadToEnd();       
       } 
      } 
      else 
      { 
       responseMessage = response.StatusDescription; 
      } 
     } 
    } 

    private static byte[] ToByteArrayUsingDataContractSer<T>(T requestBody) 
    { 
     byte[] bytes = null; 
     var serializer1 = new DataContractSerializer(typeof(T));    
     var ms1 = new MemoryStream();    
     serializer1.WriteObject(ms1, requestBody); 
     ms1.Position = 0; 
     var reader = new StreamReader(ms1); 
     bytes = ms1.ToArray(); 
     return bytes;    
    } 

REMARQUE: Assurez-vous que votre Upload objet à la fois sur le client et le serveur ont le même espace de noms et les propriétés définies afin de vous éviter tout problème de désérialisation.

+0

salut rajesh j'ai essayé votre code mais toujours je am getting Le serveur distant a renvoyé une erreur: (400) Bad Request. tout autre moyen de le faire? – VijayMathew

+0

Quelle est la taille d'image que vous essayez de télécharger? – Rajesh

+0

merci pour votre réponse. Taille de l'image est 826kb.tout paramètre spécial à faire dans le fichier web.config? S'il vous plaît laissez-moi savoir .. – VijayMathew

1

L'augmentation de la longueur de la file d'attente des messages dans web.config résout mon problème.

<webHttpBinding> 
     <binding name="streamWebHttpbinding" transferMode="Streamed" maxReceivedMessageSize="1000000000000" receiveTimeout="01:00:00" sendTimeout="01:00:00" /> 
     </webHttpBinding> 

Merci à tous

+0

Fonctionnement très bien. Merci :) – sachin10

Questions connexes