2013年7月29日 星期一

WCF Restful Web Service - 上傳及下載圖片檔案 (Upload & Download Image File)

此處將展現如何開發具備圖檔上傳、下載功能的 WCF Restful Web Service,並以 Windows Form Application 呼叫該 Web Service 的方式進行測試。

測試環境

Windows XP Professional SP3, .NET Framework 4.0, IIS 5, Visual Stdio 2010 (均安裝於同一台 PC)


前置作業

1) 建立網頁的實體目錄 C:\MyWebSite,並於該目錄下,建立 bin、image、service 三個子目錄 (Ex: C:\MyWebSite\bin)。

2) 建立存放上傳檔案的目錄 C:\MyUploadImage 。

3) 將複製一個 JPG 檔 (小於 1 MB) 至 C:\MyWebSite\image,並將其更名為 Boring_Face.jpg 。


建置測試網站

1) 呼叫 IIS 管理介面:開始 --> 設定 --> 控制台 --> 系統管理工具 --> Internet Information Services

2) 於 Internet Information Services 畫面中,依下列圖示進行操作。








3) 此時測試網站已建置完成,再依下列圖示設定 .NET 版本。




建置 WCF Restful Web Service

1) 建立一個名為 MyImageService 的 "WCF 服務應用程式" 專案。


2) 將此專案中的 IService1.cs 更名為 IImageService.cs:在方案總管中,將滑鼠指標移至 IService1.cs 並按下滑鼠右鍵;此時將出現選項,點選 "重新命名" 後,再輸入 IImageService.cs。


3) 將此專案中的 Service1.svc 更名為 ImageService.svc
3-1) 在方案總管中,將滑鼠指標移至 Service1.svc 並按下滑鼠右鍵;此時將出現選項,點選 "重新命名" 後,再輸入 ImageService.svc。


3-2) 在方案總管中,將滑鼠指標移至 Service1.svc 並按下滑鼠右鍵;此時將出現選項,點選 "檢視標記" 後,於出現的 ImageService.svc 檔案內容中,將 Service1 改為 ImageService。



3-3) 將ImageService.svc.cs 程式碼的 Service1 改為 ImageService。


4) IImageService.cs 程式內容
using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.ServiceModel.Description;
using System.IO;


namespace MyImageService
{
    [ServiceContract]
    public interface IImageService
    {
        [OperationContract]
        [WebInvoke(Method = "GET",
            UriTemplate = "/DownloadImage")]
        Stream DownloadImage();

        [OperationContract]
        [WebInvoke(Method = "POST",
            UriTemplate = "/UploadImage?name={filename}")]
        void UploadImage(string filename, Stream picture);
    }
}

5) ImageService.svc.cs 程式內容
using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.ServiceModel.Description;
using System.IO;


namespace MyImageService
{
    public class ImageService : IImageService
    {
        public Stream DownloadImage()
        {
            FileStream targetStream = File.OpenRead(@"C:\MyWebSite\Image\Boring_Face.jpg");
            WebOperationContext.Current.OutgoingResponse.ContentType = "image/jpg";
            return targetStream;
        }

        public void UploadImage(string filename, Stream picture)
        {
            byte[] buffer = new byte[1024];
            string path = Path.Combine(@"C:\MyUploadImage\", filename);
            int length = 0;

            using (Stream targetStream = File.Create(path))
            {
                while ((length = picture.Read(buffer, 0, buffer.Length)) > 0)
                {
                    targetStream.Write(buffer, 0, length);
                }
            }
        }
    }
}

6) web.config 的 "system .serviceModel" 部分請依以下設定 (maxreceivedmessagesize 表示上傳圖片的最大 byte 數,此處設定為 1M bytes。)

  
    
  

  
  
    
      
    
  

  
    
      
        
      
    
    
      
        
        
        
        
      
    
  
  


7) 建置專案
※ 若發生 "命名空間 'System.ServiceModel' 中沒有型別或命名空間名稱 'Web' (您是否遺漏了組件參考?)" 錯誤時,請參考這篇文章


8) 將建置所產生的 MyImageService.dll 複製到 C:\MyWebSite\bin 。

9) 將建置所產生的 ImageService.svc 複製到 C:\MyWebSite\service 。

10) 將 Web.config 複製到 C:\MyWebSite 。


建置 Client Winform 程式

1) 建立一個名為 MyImageService_Client 的 "Windows Form 應用程式" 專案。


2) 將畫面設置如下:

3) Form1.cs 程式內容
using System;
using System.Drawing;
using System.Windows.Forms;
using System.IO;
using System.Net;


namespace MyImageService_Client
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }


        private void btn_Download_Click(object sender, EventArgs e)
        {
            try
            {
                string url = "http://127.0.0.1/MyWebSite/Service/ImageService.svc/DownloadImage";
                HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
                request.Method = "GET";
                request.ContentType = "image/jpeg";

                using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
                {
                    Stream resultStream = response.GetResponseStream();
                    pictureBox1.Image = new Bitmap(resultStream);
                    response.Close();
                }

                lbl_Message.Text = "Download Successfully!";
            }
            catch (Exception ex)
            {
                lbl_Message.Text = ex.Message.ToString();
            }
        }


        private void btn_Upload_Click(object sender, EventArgs e)
        {
            try
            {
                string url = "http://127.0.0.1/MyWebSite/Service/ImageService.svc/UploadImage?name=TEST.jpg";
                HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
                request.Method = "POST";
                request.ContentType = "image/jpeg";

                using (Stream requestStream = request.GetRequestStream())
                {
                    byte[] bytes = File.ReadAllBytes(@"C:\MyWebSite\image\Boring_Face.jpg");
                    requestStream.Write(bytes, 0, bytes.Length);
                }

                HttpWebResponse resp = (HttpWebResponse)request.GetResponse();
                lbl_Message.Text = "Upload Successfully!";
            }
            catch (Exception ex)
            {
                lbl_Message.Text = ex.Message.ToString();
            }
        }
    }
}


實際測試

1) 執行 MyImageService_Client (可於 Visual Studio 或產生 MyImageService_Client.exe 執行之),此時將出現剛才設計的視窗,點選 "Download" 功能鍵,下載 Boring_Face.jpg 的圖檔內容。



2) 點選 "Upload" 功能鍵,將圖檔上傳至 C:\MyUploadImage\TEST.jpg



3) 可見到圖檔已成功上傳。