在我的MVC应用程序中,我使用dropzone控件来允许用户从本地系统上传文件到SQL数据库。
if (Request.Files.Count > 0)
{
var name = Request.Files[0].FileName;
var size = Request.Files[0].ContentLength;
var type = Request.Files[0].ContentType;
var fileStream = Request.Files[0].InputStream;
byte[] documentBytes = new byte[fileStream.Length];
fileStream.Read(documentBytes, 0, documentBytes.Length);
Documents databaseDocument = new Documents
{
FileContent = documentBytes,
DocumentName = System.IO.Path.GetFileName(name),
DocumentSize = size,
DocumentType = type
};
bool result = this.updateService.SaveDocument(databaseDocument);
}
"updateService"实际上是对WCF服务的引用。我在上面的代码中得到"SaveDocument"调用的错误。我已经设置了uploadReadAheadSize(在applicationHost.config),和maxReceivedMessageSize(在WCF和Web配置文件)在其他论坛上的建议。
这会给出一个错误提示"远程服务器返回了一个错误:(413)请求实体太大"
如果你不想在传输太大的对象时遇到问题,你可以使用流作为服务操作的参数。
服务接口:[ServiceContract]
public interface IStreamedService
{
[OperationContract]
void PrepareUpload(long fileLength, string fileName);
[OperationContract]
void UploadFile(Stream fileStream);
}
服务实现:public class StreamedService : IStreamedService
{
private static long lengthOfFile;
private static string nameOfFile;
public void PrepareUpload(long fileLength, string fileName)
{
lengthOfFile = fileLength;
nameOfFile = fileName;
}
public void UploadFile(Stream fileStream)
{
if(lengthOfFile==0 || string.IsNullOrEmpty(nameOfFile))
throw new ArgumentException("Upload must be prepared");
var bytes = new byte[lengthOfFile];
var numberOfBytesToRead = bytes.Length;
var numberOfReadBytes = 0;
while (numberOfBytesToRead > 0)
{
var n = fileStream.Read(bytes, numberOfReadBytes, numberOfBytesToRead);
if (n == 0)
break;
numberOfReadBytes += n;
numberOfBytesToRead -= n;
}
var fsOut = new FileStream(string.Format(@"c:temp{0}", nameOfFile), FileMode.Create);
fsOut.Write(bytes, 0, numberOfReadBytes);
fsOut.Close();
}
}
服务配置:system.serviceModel>
<services>
<service name="StreamedService.StreamedService">
<endpoint address="net.tcp://localhost:60000/StreamedService"
binding="netTcpBinding" bindingConfiguration="NewBinding0" contract="Contracts.IStreamedService" />
</service>
</services>
<bindings>
<netTcpBinding>
<binding name="NewBinding0" transferMode="Streamed" maxReceivedMessageSize="67108864" />
</netTcpBinding>
</bindings>
客户机实现: var proxy = new ChannelFactory<IStreamedService>("MyEndpoint").CreateChannel();
var fs = new FileStream(@"c:tempFileToUpload.zip", FileMode.Open);
proxy.PrepareUpload(fs.Length, "uploadedFile.zip");
proxy.UploadFile(fs);
客户端配置:
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NewBinding0" transferMode="Streamed" maxReceivedMessageSize="67108864" />
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://localhost:60000/StreamedService"
binding="netTcpBinding" bindingConfiguration="NewBinding0"
contract="Contracts.IStreamedService" name="MyEndpoint">
</endpoint>
</client>
</system.serviceModel>
上面的代码也适用于basicHttpBinding。当然,您可以在服务器端使用MemoryStream而不是FileStream,然后将其反序列化为您想要保存到DB的某些实体。