2012-07-16 52 views
3

我正在创建一个WCF Rest服务来从移动应用程序上传图像。但我得到 远程服务器返回错误:(400)错误的请求。任何人都可以指出我做错了什么。 以下是我的定义:无法将图像上传到WCF Rest服务

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

PublicMessage PostImage(Upload obj); 

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

服务定义:

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" }; 
    } 

客户端应用程序:

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); 

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> 

由于

维杰

+0

也请清理你的代码示例 - 缩进很糟糕,也有在客户端代码,这将防止它在目前的状态显然编译C#的错误。 – 2012-07-16 16:15:52

+0

尝试删除身体的风格,看看它是否工作。同时请张贴您的StreamToByte方法如何? – Rajesh 2012-07-16 16:22:33

+0

我已经用示例代码更新了我的答案。抱歉耽搁了。 – Rajesh 2012-07-31 10:02:42

回答

0

如果你没有在文件上传类的任何其他属性然后更改WCF服务方法有流PARAM,而不是在一个类中,如下包裹它:

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

然后你可以使用WebClient类直接上传文件,如下所示:

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); 

也请参阅本link

UPDATE

请找样本,让您的代码如下工作:

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

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

现在实现了PostImage你的方法如下所示:

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" }; 
} 

现在,因为我们的服务器端代码已完成,现在转移到客户端部分,将您的文件上传到服务器,如下所示:

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;    
    } 

注意:确保客户端和服务器上的Upload对象具有相同的命名空间和属性,以避免任何反序列化问题。

+0

嗨rajesh我试过你的代码,但我仍然正在获取远程服务器返回错误:(400)错误的请求。任何其他方式来做到这一点? – VijayMathew 2012-07-17 07:45:50

+0

您试图上传的图片大小是多少? – Rajesh 2012-07-17 08:41:54

+0

感谢您的答复。图像大小是826kb.any web.config文件中要做的特殊设置?请让我知道.. – VijayMathew 2012-07-17 09:47:22

1

增加web.config中的消息队列长度解决了我的问题。

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

感谢所有

+0

工作得很好。谢谢 :) – sachin10 2013-09-28 05:45:01