我正在创建一个WCF Rest服务来从移动应用程序上传图像。但我得到了 远程服务器返回错误:(400)错误请求。任何人都可以指出我做错了什么。 以下是我的定义:
[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 :(得分:1)
在web.config中增加消息队列长度解决了我的问题。
<webHttpBinding>
<binding name="streamWebHttpbinding" transferMode="Streamed" maxReceivedMessageSize="1000000000000" receiveTimeout="01:00:00" sendTimeout="01:00:00" />
</webHttpBinding>
感谢所有
答案 1 :(得分:0)
如果您在Upload类上没有任何其他属性,则将WCF服务方法更改为具有Stream参数,而不是将其包装在类中,如下所示:
[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。
更新:
请找到示例以使您的代码在下面运行:
[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对象都定义了相同的命名空间和属性,以避免任何反序列化问题。