使用場景:
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