使用 WCF rest 下载文件
本文关键字:文件 下载 rest WCF 使用 | 更新日期: 2023-09-27 18:35:30
我正在使用 .net 4.0 并尝试使用 rest wcf 服务上传文件,并使用称为 upload 的方法上传文件,并使用称为下载的方法使用相同的 rest 服务下载该文件。有一个控制台应用程序将流数据发送到 wcf 服务,并且相同的控制台应用从该服务下载。控制台应用程序使用 WebChannelFactory 来连接和使用服务。
下面是来自控制台应用的代码
StreamReader fileContent = new StreamReader(fileToUpload, false);
webChannelServiceImplementation.Upload(fileContent.BaseStream );
这是 wcf 服务代码
public void Upload(Stream fileStream)
{
long filebuffer = 0;
while (fileStream.ReadByte()>0)
{
filebuffer++;
}
byte[] buffer = new byte[filebuffer];
using (MemoryStream memoryStream = new MemoryStream())
{
int read;
while ((read = fileStream.Read(buffer, 0, buffer.Length)) > 0)
{
memoryStream.Write(buffer, 0, read);
}
File.WriteAllBytes(path, buffer);
}
}
现在,在此步骤中,当我检查文件时,我注意到它的大小(以千字节为单位)与从控制台应用程序发送的原始文件相同,但是当我打开该文件时,它没有任何内容。该文件可以是任何文件类型,无论是 excel 还是 word 文档,它仍然作为空文件出现在服务器上。所有数据都去哪儿了?
我之所以做fileStream.ReadByte()>0
是因为我在某处读到,通过网络传输时,找不到缓冲区长度(这就是为什么我在尝试在服务upload
方法中获取流的长度时出现异常的原因)。这就是为什么我不使用byte[] buffer = new byte[32768];
,如许多在线示例所示,其中字节数组是固定的。
从服务下载时,我在 wcf 服务端使用此代码
public Stream Download()
{
return new MemoryStream(File.ReadAllBytes("filename"));
}
在控制台应用程序方面,我有
Stream fileStream = webChannelServiceImplementation.Download();
//find size of buffer
long size= 0;
while (fileStream .ReadByte() > 0)
{
size++;
}
byte[] buffer = new byte[size];
using (Stream memoryStream = new MemoryStream())
{
int read;
while ((read = fileContents.Read(buffer, 0, buffer.Length)) > 0)
{
memoryStream.Write(buffer, 0, read);
}
File.WriteAllBytes("filename.doc", buffer);
}
现在这个下载的文件也是空白的,因为它下载了我之前使用上面的上传代码上传的文件,即使上传的文件大小为 200 KB,它的大小也只有 16 KB。
我的代码有什么问题?任何帮助表示赞赏。
你可以使这更简单:
public void Upload(Stream fileStream)
{
using (var output = File.Open(path, FileMode.Create))
fileStream.CopyTo(output);
}
现有代码的问题在于,您调用ReadByte
并读取整个输入流,然后尝试再次读取它(但现在它在末尾)。 这意味着您的第二次读取将全部失败(循环中的read
变量将为 0,并立即爆发),因为流现在处于其末尾。
在这里,我创建了一个 WCF REST 服务。Service.svc.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace UploadSvc
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple,
InstanceContextMode = InstanceContextMode.PerCall,
IgnoreExtensionDataObject = true,
IncludeExceptionDetailInFaults = true)]
public class UploadService : IUploadService
{
public UploadedFile Upload(Stream uploading)
{
var upload = new UploadedFile
{
FilePath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString())
};
int length = 0;
using (var writer = new FileStream(upload.FilePath, FileMode.Create))
{
int readCount;
var buffer = new byte[8192];
while ((readCount = uploading.Read(buffer, 0, buffer.Length)) != 0)
{
writer.Write(buffer, 0, readCount);
length += readCount;
}
}
upload.FileLength = length;
return upload;
}
public UploadedFile Upload(UploadedFile uploading, string fileName)
{
uploading.FileName = fileName;
return uploading;
}
}
}
网络.config
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
<httpRuntime executionTimeout="100000" maxRequestLength="20000000"/>
</system.web>
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding maxBufferSize="2147483647"
maxBufferPoolSize="2147483647"
maxReceivedMessageSize="2147483647"
transferMode="Streamed"
sendTimeout="00:05:00" closeTimeout="00:05:00" receiveTimeout="00:05:00">
<readerQuotas maxDepth="2147483647"
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647"/>
<security mode="None" />
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="defaultEndpointBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="defaultServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="UploadSvc.UploadService" behaviorConfiguration="defaultServiceBehavior">
<endpoint address="" behaviorConfiguration="defaultEndpointBehavior"
binding="webHttpBinding" contract="UploadSvc.IUploadService"/>
</service>
</services>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
消费者.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Cache;
using System.Text;
namespace UploadSvcConsumer
{
class Program
{
static void Main(string[] args)
{
//WebClient client = new WebClient();
//client.UploadData("http://localhost:1208/UploadService.svc/Upload",)
//string path = Path.GetFullPath(".");
byte[] bytearray=null ;
//throw new NotImplementedException();
Stream stream =
new FileStream(
@"C:'Image'hanuman.jpg"
FileMode.Open);
stream.Seek(0, SeekOrigin.Begin);
bytearray = new byte[stream.Length];
int count = 0;
while (count < stream.Length)
{
bytearray[count++] = Convert.ToByte(stream.ReadByte());
}
string baseAddress = "http://localhost:1208/UploadService.svc/";
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(baseAddress + "Upload");
request.Method = "POST";
request.ContentType = "text/plain";
request.KeepAlive = false;
request.ProtocolVersion = HttpVersion.Version10;
Stream serverStream = request.GetRequestStream();
serverStream.Write(bytearray, 0, bytearray.Length);
serverStream.Close();
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
int statusCode = (int)response.StatusCode;
StreamReader reader = new StreamReader(response.GetResponseStream());
}
}
}
}