使用场景:
WINFORM客户端上传附件,附件通过调用WCF接口方法(POST方法,将对象转换为流,WCF接口收再转换回来),上传至服务器;
客户端(winform)调用:
/// <summary>
/// Wcf文件上传
/// </summary>
/// <param name="contentLength">文件长度(以字节为单位)。</param>
/// <param name="inputStream">文件流</param>
/// <param name="folder">上传的文件夹路径</param>
/// <param name="fileName">文件名称</param>
public static void WcfFileUp(int contentLength, Stream inputStream, string folder, string fileName, WJXX wjxx)
{
int UPLENGTH = 1048576;
System.IO.Stream stream = inputStream;
stream.Position = 0;//这边置为0是因为我们不做断点续传,如果要做断点续传的话这边就是上次传输中断时候的位置
byte[] buffer;
string wxurl = "http://...../Service.svc/UploadFile";//调用WCF服务
var myWebClient = new WebClient();//模拟网页POST请求
myWebClient.Credentials = CredentialCache.DefaultCredentials;
try
{
bool b = false;
do
{
long i = (stream.Length - stream.Position);
if (i < 0)
{
i = stream.Length;
}
if (i > UPLENGTH)
{
//UPLENGTH是流模块的长度,分块时,每次上传模块的大小
buffer = new byte[UPLENGTH];
stream.Read(buffer, 0, UPLENGTH);
}
else
{
buffer = new byte[i];
stream.Read(buffer, 0, (int)i);
}
if (buffer.Length < 1)
break;
Hashtable parames = new Hashtable();
parames.Add("fileBytes", buffer);//文件块
parames.Add("position", stream.Position);//文件流开始位置
parames.Add("fileStreamLength", contentLength);//文件长度
parames.Add("folder", folder);//文件夹
parames.Add("fileName", fileName);//文件名46
//自定义的参数
parames.Add("SJLYBM", wjxx.SJLYBM);//附件来源表名
parames.Add("SJLYBXXBS", wjxx.SJLYBXXBS);//来源表数据主键
parames.Add("CJR", wjxx.CJR);//上传人
parames.Add("CJSJ", DateTime.Now.ToString());//上传时间
byte[] tBytes = null;
using (MemoryStream memoryStream = new MemoryStream())
{
//将对象转为流模式
BinaryFormatter binaryFormatter = new BinaryFormatter();
binaryFormatter.Serialize(memoryStream, parames);
tBytes = memoryStream.ToArray();
}
//POST数据到Wcf中处理
byte[] responseArray = myWebClient.UploadData(wxurl, "POST", tBytes);
//返回处理的结果
string result = System.Text.Encoding.Default.GetString(responseArray, 0, responseArray.Length);
b = result == "true";
}
while (b == false);
}
catch (Exception ex)
{
throw ex;
}
finally
{
stream.Close();
}
}
WCF服务端:
IService:
[OperationContract]
[WebInvoke(UriTemplate = "UploadFile", Method = "POST", RequestFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Bare,ResponseFormat = WebMessageFormat.Json)]
bool UploadFile(Stream stream);
Service.svc
/// <summary>
/// 上传文件
/// </summary>
public bool UploadFile(Stream stream)
{
return new ....().UploadFile(stream);
}
方法定义:
/// <summary>
/// 文件上传(分块上传,支持断点续传)
/// </summary>
/// <param name="stream"></param>
/// <returns></returns>
[OperationContract]
[WebInvoke(Method = "POST")]
public bool UploadFile(Stream stream)
{
//WebInvoke Method要记得置为POST模式
try
{
BinaryFormatter binaryFormatter = new BinaryFormatter();
//将对象转化为Hashtable对象
Hashtable parames = binaryFormatter.Deserialize(stream) as Hashtable;
long position = (long)parames["position"];
int fileStreamLength = (int)parames["fileStreamLength"];
string folder = Convert.ToString(parames["folder"]);
string fileName = Convert.ToString(parames["fileName"]);
byte[] fileBytes = (byte[])parames["fileBytes"];
bool result = false;
string folderPath = System.AppDomain.CurrentDomain.BaseDirectory + @"service\" + folder;
//创建保存文件夹
if (!Directory.Exists(folderPath))
{
Directory.CreateDirectory(folderPath);
}
string url_Post = folderPath + @"\" + fileName;
//Path.Combine(folderPath, fileName)
using (FileStream fs = new FileStream(url_Post, FileMode.OpenOrCreate, FileAccess.ReadWrite))
{
//写入到文件
fs.Position = fs.Length;
fs.Write(fileBytes, 0, fileBytes.Length);
if (fs.Length == fileStreamLength)
{
result = true;
}
}
if (result)
{
string SJLYBM = Convert.ToString(parames["SJLYBM"]);
string SJLYBXXBS = Convert.ToString(parames["SJLYBXXBS"]);
string CJR = Convert.ToString(parames["CJR"]);
string CJSJ = Convert.ToString(parames["CJSJ"]);
string data = "{}";
result = new ...().Save_YJZH_WJ(data);//自定义业务方法
}
return result;
}
catch (Exception ex)
{
return false;
}
}
}
WCF服务Config文件配制:
WCF的流模式只支持如下四种:1:BasicHttpBinding 2:NetTcpBinding 3:NetNamedPipeBinding 4:WebHttpBinding.
1.设置TransferMode。它支持四种模式(Buffered、Streamed、StreamedRequest、StreamedResponse),请根据具体情况设置成三种Stream模式之一。
2.修改MaxReceivedMessageSize。该值默认大小为64k,因此,当传输数据大于64k时,则抛出CommunicationException异常。
3.修改receiveTimeout 和sendTimeout。大数据传送时间较长,需要修改这两个值,以免传输超时。
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="webHttp">
<webHttp/>
<!--<enableWebScript />如果需要支持脚本调用请启用此项-->
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="YJ_Service_PostSerBeh">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="YJ_Service_PostSerBeh" name="YJ_Service.Service">
<endpoint address=""
binding="webHttpBinding"
contract="YJ_Service.IService"
behaviorConfiguration="webHttp"
bindingConfiguration="webBinding"
name="post" />
<endpoint address="mex" binding="mexHttpBinding" name="mex" contract="IMetadataExchange"/>
</service>
</services>
<bindings>
<webHttpBinding>
<binding name="webBinding" maxBufferSize="2147483647" maxBufferPoolSize="2147483647"
maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
</binding>
</webHttpBinding>
<netTcpBinding>
<binding name="MyTcpBinding"
maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647"
sendTimeout="00:30:00" transferMode="Streamed">
</binding>
</netTcpBinding>
</bindings>
</system.serviceModel>
程序实现参照:
http://www.gkxsn.com/6353693949449511011.html