天天看點

WCF大檔案上傳

使用場景:

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