close

  上篇大致上說明了MTOM的相關資訊,而這篇將開始講程式實作的部份,由於這程式有Client及WS兩端的程式,所以這次將以WS端的來講,而這Client端的AP將會長的像下面的樣子,一共有四個功能,取得取單/上傳/下載,還有一個檔案驗證功能.



Web.Config的設定如下:


01 <?xml version="1.0"?>
02 <configuration>
03  <configSections>
04      <section name="microsoft.web.services3" type="Microsoft.Web.Services3.Configuration.WebServicesConfiguration, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
05  </configSections>
06  <appSettings>
07      <add key="UploadPath" value="Upload"/>
08  </appSettings>
09  <connectionStrings/>
10  <system.web>
11     <compilation debug="true">
12    <assemblies>
13        <add assembly="Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
14    </assemblies>
15      </compilation>
16      <authentication mode="Windows"/>
17      <webServices>
18    <soapExtensionImporterTypes>
19        <add type="Microsoft.Web.Services3.Description.WseExtensionImporter, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
20    </soapExtensionImporterTypes>
21    <soapServerProtocolFactory type="Microsoft.Web.Services3.WseProtocolFactory, Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
22      </webServices>
23     <httpRuntime maxRequestLength="16384"></httpRuntime>
24  </system.web>
25  <microsoft.web.services3>
26      <messaging>
27    <mtom serverMode="always"/>
28     </messaging>
29  </microsoft.web.services3>
30 </configuration>
31

從這個config裡可以看到幾行不是WSE就是MTOM,這些值要怎麼來?我們可以用WSE的Configuration Tool來設定,程式剛開啟時像下面一樣是空白的.



這時從File -> Open,開啟web.config這個檔案,就可以開始設定的動作(Client端的設定也會用到此工具,但設定不太相同),以下的設定就以畫面的方式直接顯示.



(其它用預設值,不過有興趣的人,可以再針對每個細項設定去瞭解)



設定完再把它給存檔即可,那麼Web.Config就會設好WSE MTOM的部份.


 


接下來的Web Service的部份程式碼如下 :


public class ServiceMTOM : System.Web.Services.WebService
{
    private string UploadPath;
    public ServiceMTOM()
    {
        // 檢查上傳路徑是否存在
        string uploadConfigSetting = ConfigurationManager.AppSettings["UploadPath"].ToString();
        if (Path.IsPathRooted(uploadConfigSetting))
        {
            UploadPath = uploadConfigSetting;
        }

        else
        {
            UploadPath = Server.MapPath(uploadConfigSetting);
        }


        if (!Directory.Exists(UploadPath))
        {
            Directory.CreateDirectory(Server.MapPath(uploadConfigSetting));
        }

    }


    #region Upload
    /// <summary>
    /// 上傳檔案
    /// </summary>
    /// <param name="FileName">檔案名稱 string</param>
    /// <param name="buffer">傳輸量 long</param>
    /// <param name="Offset">檔案起始 long</param>
    [WebMethod]

    public void AppendChunk(string FileName, byte[] buffer, long Offset)
    {
            string FilePath = Path.Combine(UploadPath, FileName);

            if (Offset == 0)    // 如果起始為0,則產生一個新檔.
            {
                File.Create(FilePath).Close();
            }

            else if (!File.Exists(FilePath))
            {
                CustomSoapException("檔案不存在", String.Format("檔案 : {0} 不存在", FilePath));
            }

            long FileSize = new FileInfo(FilePath).Length;
            if (FileSize < Offset)
            {
                CustomSoapException("檔案Offset錯誤", "Offset大於檔案長度");
            }


            //開啟檔案寫入.
            try
            {
public class ServiceMTOM : System.Web.Services.WebService
{
    private string UploadPath;
    public ServiceMTOM()
    {
        // 檢查上傳路徑是否存在
        string uploadConfigSetting = ConfigurationManager.AppSettings["UploadPath"].ToString();
        if (Path.IsPathRooted(uploadConfigSetting))
        {
            UploadPath = uploadConfigSetting;
        }

        else
        {
            UploadPath = Server.MapPath(uploadConfigSetting);
        }


        if (!Directory.Exists(UploadPath))
        {
            Directory.CreateDirectory(Server.MapPath(uploadConfigSetting));
        }

    }


    #region Upload
    /// <summary>
    /// 上傳檔案
    /// </summary>
    /// <param name="FileName">檔案名稱 string</param>
    /// <param name="buffer">傳輸量 long</param>
    /// <param name="Offset">檔案起始 long</param>
    [WebMethod]

    public void AppendChunk(string FileName, byte[] buffer, long Offset)
    {
            string FilePath = Path.Combine(UploadPath, FileName);

            if (Offset == 0)    // 如果起始為0,則產生一個新檔.
            {
                File.Create(FilePath).Close();
            }

            else if (!File.Exists(FilePath))
            {
                CustomSoapException("檔案不存在", String.Format("檔案 : {0} 不存在", FilePath));
            }

            long FileSize = new FileInfo(FilePath).Length;
            if (FileSize < Offset)
            {
                CustomSoapException("檔案Offset錯誤", "Offset大於檔案長度");
            }


            //開啟檔案寫入.
            try
            {
using (FileStream fs = new FileStream(FilePath, FileMode.Open, FileAccess.ReadWrite, FileShare.Read))
                {
                    fs.Seek(Offset, SeekOrigin.Begin);
                    fs.Write(buffer, 0, buffer.Length);
                }

            }

            catch (Exception ex)
            {
                CustomSoapException("檔案寫入錯誤", ex.Message);
            }

    }

    #endregion


    #region Download
    /// <summary>
    /// 下載檔案
    /// </summary>
    /// <param name="FileName">檔案名稱 string</param>
    /// <param name="Offset">檔案起始 long</param>
    /// <param name="BufferSize">傳輸量 long</param>
    /// <returns>檔案 byte[]</returns>
    [WebMethod]

    public byte[] DownloadChunk(string FileName, long Offset, int BufferSize)
    {
            string FilePath = Path.Combine(UploadPath, FileName);

            //檢查檔案是否存在
            if (!File.Exists(FilePath))
                CustomSoapException("檔案不存在", String.Format("檔案 : {0} 不存在", FilePath));

            long FileSize = new FileInfo(FilePath).Length;

            //如果檔案起始位置大於檔案長度
            if (Offset > FileSize)
                CustomSoapException("錯誤的下載位置", String.Format("檔案大小為 {0}, 要求的起始位置為 {1}", FileSize, Offset));


            byte[] TmpBuffer;
            int BytesRead;

            try
            {
                //開啟檔案
                using (FileStream fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    fs.Seek(Offset, SeekOrigin.Begin);    // 找到要求的檔案起始位置
                    TmpBuffer = new byte[BufferSize];
                    BytesRead = fs.Read(TmpBuffer, 0, BufferSize);    // 把資料讀入buffer內
                }


                if (BytesRead != BufferSize)
                {
                    //最後一個檔案長度buffer可能會比BufferSize少,所以必需改變buffer的長度,以符合實際檔案長度.
                    byte[] TrimmedBuffer = new byte[BytesRead];
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 jeffyeh 的頭像
    jeffyeh

    jeffyeh

    jeffyeh 發表在 痞客邦 留言(0) 人氣()