1,创建Web服务
新建-项目-Web-Asp.net服务应用程序,把HelloWorld给删除,ReverseString方法,如下:
代码:
using System; using System.Collections; using System.ComponentModel; using System.Data; using System.Linq; using System.Web; using System.Web.Services; using System.Web.Services.Protocols; using System.Xml.Linq; namespace WebService2 { /// <summary> /// Service1 的摘要说明 /// </summary> [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [ToolboxItem(false)] // 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消对下行的注释。 // [System.Web.Script.Services.ScriptService] public class Service1 : System.Web.Services.WebService { [WebMethod] public string ReverseString(string message) //新建这个方法 { char[] arr = message.ToCharArray(); Array.Reverse(arr); message = new string(arr); return message; } } }
测试服务:
点击方法,输入abcde,点调用
测试结果:
返回xml,edcba 测试正确。
2,在Windows Forms 中调用Web服务
新建Windows Forms 工程,注意上面服务不要关,干脆双开VS吧,免得出问题。项目-添加服务引用,地址中输入Web服务的地址,上例:http://localhost:1241/Service1.asmx,如果Web服务已经发布,请填写发布的地址。
找到服务后确定:
在Form上加入两个TextBox,一个Button,双击Button,编写事件。
代码:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace WindowsFormsApplication9 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { ServiceReference1.Service1SoapClient ws = new ServiceReference1.Service1SoapClient(); textBox2.Text = ws.ReverseString(textBox1.Text); } } }
运行结果:
3,异步调用服务
由于web服务在网络上使用,所以如果网速不好,或服务器端忙很长时间没有相应的话,那么执行调用的程序将阻塞,以至界面卡死,不能相应。如何在调用服务的时候不阻塞呢?就是采用异步调用服务的方式。服务端不用修改,只修改客户端就可以了。
首先,在解决方案管理器的Service Reference中,右键该引用,点配置服务引用。如下画面:
选中【生成异步操作】,确定。
代码:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace WindowsFormsApplication9 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { //ServiceReference1.Service1SoapClient ws = new ServiceReference1.Service1SoapClient(); //textBox2.Text = ws.ReverseString(textBox1.Text); ServiceReference1.Service1SoapClient client = new ServiceReference1.Service1SoapClient(); //client.ReverseStringCompleted += new EventHandler<ServiceReference1.ReverseStringCompletedEventArgs>(client_ReverseStringCompleted); client.ReverseStringCompleted += client_ReverseStringCompleted; //简易写法 client.ReverseStringAsync(textBox1.Text); } private void client_ReverseStringCompleted(object sender, ServiceReference1.ReverseStringCompletedEventArgs e) { textBox2.Text = e.Result; } } }
为了让测试更加逼真,可以在服务器端,加入演示,模拟服务器或网络的延时。
服务端代码:
using System; using System.Collections; using System.ComponentModel; using System.Data; using System.Linq; using System.Web; using System.Web.Services; using System.Web.Services.Protocols; using System.Xml.Linq; namespace WebService2 { /// <summary> /// Service1 的摘要说明 /// </summary> [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [ToolboxItem(false)] // 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消对下行的注释。 // [System.Web.Script.Services.ScriptService] public class Service1 : System.Web.Services.WebService { [WebMethod] public string ReverseString(string message) //新建这个方法 { char[] arr = message.ToCharArray(); Array.Reverse(arr); message = new string(arr); System.Threading.Thread.Sleep(5000);//为了证明异步的效果特添加延时 return message; } } }
运行结果:在等待服务器返回的时间内,界面没有卡死,证明异步调用成功。
4,ASP.NET客户程序
上面是在Windows Forms 里完成的Web服务调用,现在用ASP.NET来调用相同的服务。
基本与Windows Forms类似,首先添加Web服务引用,然后添加代码如下:
using System; using System.Configuration; using System.Data; using System.Linq; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Xml.Linq; public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } protected void Button1_Click(object sender, EventArgs e) { ServiceReference1.Service1SoapClient client = new ServiceReference1.Service1SoapClient(); TextBox2.Text = client.ReverseString(TextBox1.Text); } }
运行结果:
5,类的传递
上面的例子是简单是数据类型,现在试一下传递一个自定义类。
服务器端代码:
using System; using System.Collections; using System.ComponentModel; using System.Data; using System.Linq; using System.Web; using System.Web.Services; using System.Web.Services.Protocols; using System.Xml.Linq; namespace WebService2 { public enum TemperatureType { Fahrenheit, Celsius } public enum TemparatureCondition { Rainy, Sunny, Cloudy, Thunderstorm } public class GetWeatherRequest { public string City; public TemperatureType TemperatureType; } public class GetWeatherResponse { public TemparatureCondition Condition; public int Temperature; } /// <summary> /// Service1 的摘要说明 /// </summary> [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [ToolboxItem(false)] // 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消对下行的注释。 // [System.Web.Script.Services.ScriptService] public class Service1 : System.Web.Services.WebService { [WebMethod] public string ReverseString(string message) //新建这个方法 { char[] arr = message.ToCharArray(); Array.Reverse(arr); message = new string(arr); System.Threading.Thread.Sleep(5000);//为了证明异步的效果特添加延时 return message; } [WebMethod] public GetWeatherResponse GetWeather(GetWeatherRequest req) { GetWeatherResponse resp = new GetWeatherResponse(); Random r = new Random(); int celsius = r.Next(-20, 50); if (req.TemperatureType == TemperatureType.Celsius) resp.Temperature = celsius; else resp.Temperature = (212 - 32) / 100 * celsius + 32; if (req.City == "Redmond") resp.Condition = TemparatureCondition.Rainy; else resp.Condition = (TemparatureCondition)r.Next(0, 3); return resp; } } }
客户端代码:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using WindowsFormsApplication10.ServiceReference1;//加上,认识一下需要传递的参数类,以及返回的类。 namespace WindowsFormsApplication10 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void label2_Click(object sender, EventArgs e) { } private void button1_Click(object sender, EventArgs e) { GetWeatherRequest req = new GetWeatherRequest();//有了最上面那个using这下找到这个类了吧,不然肯定找不到。 if (radioButton1.Checked) { req.TemperatureType = TemperatureType.Celsius; } else { req.TemperatureType = TemperatureType.Fahrenheit; } req.City = textBox1.Text; Service1SoapClient client = new Service1SoapClient(); GetWeatherResponse resp = client.GetWeather(req); textBox2.Text = resp.Condition.ToString(); textBox3.Text = resp.Temperature.ToString(); } } }
运行结果: