<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
{
/// <summary>
/// Service1 的摘要說明
/// </summary>
[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 <= 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<Student> GetList()
List<Student> list = new List<Student>();
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個多小時
<webServices>
<protocols>
<add name="HttpPost" />
<add name="HttpGet" />
</protocols>
</webServices>
4、在WinForm應用程式裡添加Web引用,有人會發現選擇WinForm項目裡隻能添加服務引用,我當初也是這麼認為後來,後來發現在做異步的調用的時候有些方法實在點不出來,是以這裡說下如何添加Web引用,選擇項目WinFormInvokeWebService右鍵->添加服務引用,彈出以下對話框
(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("&lt;", "<");
strValue = strValue.Replace("&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");
/// <summary>
/// 界面的進度條顯示
/// </summary>
void ChangeProcessBar()
for (int i = 0; i < 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)
運作結果: