天天看點

WinForm如何調用Web Service

<a href="http://blog.csdn.net/aspnet2002web/article/details/6074463" target="_blank">參考位址</a>

今天看了李天平關于WinForm調用Web Service的代碼,我自己模仿做一個代碼基本都是複制粘貼的,結果不好使。郁悶的是,又碰到那個該死的GET調用Web Service,我想肯定又是Web.config需要配置,結果WinForm沒有這個配置檔案,奇怪,為什麼人家的就好使,我寫的就不好使呢。

上網搜吧,唉,找個兩個多小時,基本都是和我一樣的代碼,互相轉載。根本沒人提代碼好不好使,也沒人提正确的用法。就在我要放棄的時候,終于發現原來是在 Web Service的Web.config裡配置的(下面滴2步),真是欲哭無淚啊,大家可要注意啊。

好了,把過程詳細說下吧。

1、建立項目WebService和WinForm項目,這裡起名為WinFormInvokeWebService,如圖所示,

2、Service1.asmx代碼為:(這部分其實和上篇的代碼是一樣的)

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Services;

using System.Data;

namespace WebService1

{

    /// &lt;summary&gt;

    /// Service1 的摘要說明

    /// &lt;/summary&gt;

    [WebService(Namespace = "http://tempuri.org/")]

    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

    [System.ComponentModel.ToolboxItem(false)]

    // 若要允許使用 ASP.NET AJAX 從腳本中調用此 Web 服務,請取消對下行的注釋。

    [System.Web.Script.Services.ScriptService]

    public class Service1 : System.Web.Services.WebService

    {

        //無參方法

        [WebMethod]

        public string HelloWorld()

        {

            return "Hello World";

        }

        //有參方法1

        public int Add(int a, int b)

            return a + b;

        //有參方法2

        public int Sum(int x)

            int sum = 0;

            for (int i = 0; i &lt;= x; i++)

            {

                sum += i;

            }

            return sum;

        // 傳回一個複合類型

        public  Student GetStudentByStuNo(string stuNo)

            if(stuNo=="001")

                return new Student { StuNo = "001", StuName = "張三" };

            if(stuNo=="002")

                return new Student { StuNo = "002", StuName = "李四" };

            return null;

        //傳回傳回泛型集合的

        public List&lt;Student&gt; GetList()

            List&lt;Student&gt; list = new List&lt;Student&gt;();

            list.Add(new Student() { StuNo = "001", StuName = "張三" });

            list.Add(new Student() { StuNo = "002", StuName = "李四" });

            list.Add(new Student() { StuNo = "003", StuName = "王五" });

            return list;

        //傳回DataSet

        public  DataSet GetDataSet()

            DataSet ds = new DataSet();

            DataTable dt = new DataTable();

            dt.Columns.Add("StuNo", Type.GetType("System.String"));

            dt.Columns.Add("StuName", Type.GetType("System.String"));

            DataRow dr = dt.NewRow();

            dr["StuNo"] = "001"; dr["StuName"] = "張三";

            dt.Rows.Add(dr);

            dr = dt.NewRow();

            dr["StuNo"] = "002"; dr["StuName"] = "李四";

            ds.Tables.Add(dt);

            return ds;

    }

    public class Student

        public string StuNo { get; set; }

        public string StuName { get; set; }

}

3、在WebService的web.config檔案的system.web節下面加上以下配置。如果不添加在運作手工發送HTTP請求調用WebService(利用GET方式)時,總是出現“遠端伺服器傳回錯誤: (500) 内部伺服器錯誤。”就是這個該死的錯誤,讓我浪費2個多小時

    &lt;webServices&gt;

        &lt;protocols&gt;

            &lt;add name="HttpPost" /&gt;

            &lt;add name="HttpGet" /&gt;

        &lt;/protocols&gt;

&lt;/webServices&gt;

4、在WinForm應用程式裡添加Web引用,有人會發現選擇WinForm項目裡隻能添加服務引用,我當初也是這麼認為後來,後來發現在做異步的調用的時候有些方法實在點不出來,是以這裡說下如何添加Web引用,選擇項目WinFormInvokeWebService右鍵-&gt;添加服務引用,彈出以下對話框

 (1)選擇進階

(2)選擇添加web引用

(3)選擇“此解決方案中的Web服務”

(4)選擇Service1

(5)在web引用名裡輸入一個服務名稱,這裡使用預設的名稱localhost,點添加引用

5、添加3個Windows窗體,

(1)Form1拖放的控件為:

Form1的代碼為:

using System.ComponentModel;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

namespace WinFormInvokeWebService

    public partial class Form1 : Form

        public Form1()

            InitializeComponent();

        private void button1_Click(object sender, EventArgs e)

            localhost.Service1 service = new localhost.Service1();

            localhost.Student s = service.GetStudentByStuNo("002");

            MessageBox.Show("學号:" + s.StuNo + ",姓名:" + s.StuName);

        private void button2_Click(object sender, EventArgs e)

            new Form2().Show();

        private void button3_Click(object sender, EventArgs e)

            new Form3().Show();

(2)Form2拖放的控件為:

Form2的代碼為:

//導入此命名空間

using System.Net;

using System.Xml;

using System.IO;

using System.Web;   //先添加System.Web引用再導入此命名空間

    public partial class Form2 : Form

        public Form2()

        //手工發送HTTP請求調用WebService-GET方式

            //http://localhost:3152注意你的位址可能和我的不一樣,運作WebService看下你的端口改下

            string strURL = "http://localhost:3152/Service1.asmx/GetStudentByStuNo?stuNo=";

            strURL += this.textBox1.Text;

            //建立一個HTTP請求

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(strURL);

            //request.Method="get";

            HttpWebResponse response = (System.Net.HttpWebResponse)request.GetResponse();

            Stream s = response.GetResponseStream();

            XmlTextReader Reader = new XmlTextReader(s);

            Reader.MoveToContent();

            string strValue = Reader.ReadInnerXml();

            strValue = strValue.Replace("&amp;lt;", "&lt;");

            strValue = strValue.Replace("&amp;gt;", "&gt;");

            MessageBox.Show(strValue);

            Reader.Close();

        //手工發送HTTP請求調用WebService-POST方式

            string strURL = "http://localhost:3152/Service1.asmx/GetStudentByStuNo";

            //Post請求方式

            request.Method = "POST";

            //内容類型

            request.ContentType = "application/x-www-form-urlencoded";

            //參數經過URL編碼

            string paraUrlCoded = HttpUtility.UrlEncode("stuNo");

            paraUrlCoded += "=" + HttpUtility.UrlEncode(this.textBox1.Text);

            byte[] payload;

            //将URL編碼後的字元串轉化為位元組

            payload = System.Text.Encoding.UTF8.GetBytes(paraUrlCoded);

            //設定請求的ContentLength

            request.ContentLength = payload.Length;

            //獲得請求流

            Stream writer = request.GetRequestStream();

            //将請求參數寫入流

            writer.Write(payload, 0, payload.Length);

            //關閉請求流

            writer.Close();

            //獲得響應流

            HttpWebResponse response = (HttpWebResponse)request.GetResponse();

 (3)Form3拖放的控件為:

Form3的代碼為:

    public partial class Form3 : Form

        public Form3()

        //利用Backgroundworker對象

            BackgroundWorker backgroundworker = new BackgroundWorker();

            // 注冊具體異步處理的方法

            backgroundworker.DoWork += new DoWorkEventHandler(back_DoWork);

            // 注冊調用完成後的回調方法

            backgroundworker.RunWorkerCompleted += newRunWorkerCompletedEventHandler(back_RunWorkerCompleted);

            // 這裡開始異步調用

            backgroundworker.RunWorkerAsync();

            //調用服務的同時用戶端處理并不停止

            ChangeProcessBar();

        //完成事件

        void back_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)

            if (e.Error != null)

                throw e.Error;

            progressBar1.Value = progressBar1.Maximum;                              //調用完成了,把用戶端進度條填充滿

            localhost.Student s = e.Result aslocalhost.Student;                    //擷取處理結果

            MessageBox.Show("學号:" + s.StuNo + ",姓名:" + s.StuName);            //顯示從伺服器擷取的結果值

        //調用方法

        void back_DoWork(object sender, DoWorkEventArgs e)

            // Web Service代理類

            // 調用Web方法GetClass1,結果指派給DoWorkEventArgs的Result對象

            e.Result = service.GetStudentByStuNo("002");

        /// &lt;summary&gt;

        /// 界面的進度條顯示

        /// &lt;/summary&gt;

        void ChangeProcessBar()

            for (int i = 0; i &lt; 10; i++)

                progressBar1.Value = i;

                System.Threading.Thread.Sleep(500);

        //調用WebMethod的Async方法

            //這裡開始異步調用

            //service.GetProductPriceAsync("001");

            service.GetStudentByStuNoAsync("002");

            service.GetStudentByStuNoCompleted += newlocalhost.GetStudentByStuNoCompletedEventHandler(GetStudentByStuNoCompleted);

            //調用同時用戶端處理不停止

        void GetStudentByStuNoCompleted(object sender, localhost.GetStudentByStuNoCompletedEventArgse)

 運作結果:

繼續閱讀