一、創建WebService
using System; using System.Web.Services; namespace WebService1 { /// <summary> /// Service1 的摘要說明 /// </summary> [WebService(Namespace = "http://tempuri.org/", Description="測試服務")] [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(Description="Hello World")] public string HelloWorld() { return "Hello World"; } [WebMethod(Description="A加B")] public int Add(int a, int b) { return a + b; } [WebMethod(Description="獲取時間")] public string GetDate() { return DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); } } }
服務創建后,在瀏覽器中輸入服務地址,可以看到如下圖所示。
二、通過Visual Studio添加服務引用
通過Visual Studio添加服務引用相當方便,只需要在Visual Studio中選擇添加服務引用,便可以生成代理類,在項目中通過代理調用服務,如下圖所示。
添加服務引用以后,在項目解決方案中多了Service References和app.config,如下圖所示。
ServiceReference1就是上面添加的服務,app.config是服務的配置文件,app.config里面的配置大致如下,當服務地址改變時,修改endpoint里的address即可。
<!--app.config文件配置--> <?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> </configSections> <system.serviceModel> <bindings> <basicHttpBinding> <binding name="Service1Soap" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true"> <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" /> <security mode="None"> <transport clientCredentialType="None" proxyCredentialType="None" realm="" /> <message clientCredentialType="UserName" algorithmSuite="Default" /> </security> </binding> </basicHttpBinding> </bindings> <client> <endpoint address="http://localhost:19951/Service1.asmx" binding="basicHttpBinding" bindingConfiguration="Service1Soap" contract="ServiceReference1.Service1Soap" name="Service1Soap" /> </client> </system.serviceModel> </configuration>
客戶端調用WebService
//調用服務,結果如圖所示。 static void Main(string[] args) { ServiceReference1.Service1SoapClient client = new ServiceReference1.Service1SoapClient(); //調用服務的HelloWorld方法 string hello = client.HelloWorld(); Console.WriteLine("調用服務HelloWorld方法,返回{0}", hello); //調用服務的Add方法 int a = 1, b = 2; int add = client.Add(a, b); Console.WriteLine("調用服務Add方法,{0} + {1} = {2}", a, b, add); //調用服務的GetDate方法 string date = client.GetDate(); Console.WriteLine("調用服務GetDate方法,返回{0}", date); Console.ReadKey(); }
三、 動態調用服務
using System; using System.CodeDom; using System.CodeDom.Compiler; using System.IO; using System.Net; using System.Reflection; using System.Web.Services.Description; using Microsoft.CSharp; static void Main(string[] args) { //服務地址,該地址可以放到程序的配置文件中,這樣即使服務地址改變了,也無須重新編譯程序。 string url = "http://localhost:19951/Service1.asmx"; //客戶端代理服務命名空間,可以設置成需要的值。 string ns = string.Format("ProxyServiceReference"); //獲取WSDL WebClient wc = new WebClient(); Stream stream = wc.OpenRead(url + "?WSDL"); ServiceDescription sd = ServiceDescription.Read(stream);//服務的描述信息都可以通過ServiceDescription獲取 string classname = sd.Services[0].Name; ServiceDescriptionImporter sdi = new ServiceDescriptionImporter(); sdi.AddServiceDescription(sd, "", ""); CodeNamespace cn = new CodeNamespace(ns); //生成客戶端代理類代碼 CodeCompileUnit ccu = new CodeCompileUnit(); ccu.Namespaces.Add(cn); sdi.Import(cn, ccu); CSharpCodeProvider csc = new CSharpCodeProvider(); //設定編譯參數 CompilerParameters cplist = new CompilerParameters(); cplist.GenerateExecutable = false; cplist.GenerateInMemory = true; cplist.ReferencedAssemblies.Add("System.dll"); cplist.ReferencedAssemblies.Add("System.XML.dll"); cplist.ReferencedAssemblies.Add("System.Web.Services.dll"); cplist.ReferencedAssemblies.Add("System.Data.dll"); //編譯代理類 CompilerResults cr = csc.CompileAssemblyFromDom(cplist, ccu); if (cr.Errors.HasErrors == true) { System.Text.StringBuilder sb = new System.Text.StringBuilder(); foreach (System.CodeDom.Compiler.CompilerError ce in cr.Errors) { sb.Append(ce.ToString()); sb.Append(System.Environment.NewLine); } throw new Exception(sb.ToString()); } //生成代理實例,並調用方法 Assembly assembly = cr.CompiledAssembly; Type t = assembly.GetType(ns + "." + classname, true, true); object obj = Activator.CreateInstance(t); //調用HelloWorld方法 MethodInfo helloWorld = t.GetMethod("HelloWorld"); object helloWorldReturn = helloWorld.Invoke(obj, null); Console.WriteLine("調用HelloWorld方法,返回{0}", helloWorldReturn.ToString()); //獲取Add方法的參數 ParameterInfo[] helloWorldParamInfos = helloWorld.GetParameters(); Console.WriteLine("HelloWorld方法有{0}個參數:", helloWorldParamInfos.Length); foreach (ParameterInfo paramInfo in helloWorldParamInfos) { Console.WriteLine("參數名:{0},參數類型:{1}", paramInfo.Name, paramInfo.ParameterType.Name); } //獲取HelloWorld返回的數據類型 string helloWorldReturnType = helloWorld.ReturnType.Name; Console.WriteLine("HelloWorld返回的數據類型是{0}", helloWorldReturnType); Console.WriteLine("\n=============================================================="); //調用Add方法 MethodInfo add = t.GetMethod("Add"); int a = 10, b = 20;//Add方法的參數 object[] addParams = new object[]{a, b}; object addReturn = add.Invoke(obj, addParams); Console.WriteLine("調用HelloWorld方法,{0} + {1} = {2}", a, b, addReturn.ToString()); //獲取Add方法的參數 ParameterInfo[] addParamInfos = add.GetParameters(); Console.WriteLine("Add方法有{0}個參數:", addParamInfos.Length); foreach (ParameterInfo paramInfo in addParamInfos) { Console.WriteLine("參數名:{0},參數類型:{1}", paramInfo.Name, paramInfo.ParameterType.Name); } //獲取Add返回的數據類型 string addReturnType = add.ReturnType.Name; Console.WriteLine("Add返回的數據類型:{0}", addReturnType); Console.WriteLine("\n=============================================================="); //調用GetDate方法 MethodInfo getDate = t.GetMethod("GetDate"); object getDateReturn = getDate.Invoke(obj, null); Console.WriteLine("調用GetDate方法,返回{0}", getDateReturn.ToString()); //獲取GetDate方法的參數 ParameterInfo[] getDateParamInfos = getDate.GetParameters(); Console.WriteLine("GetDate方法有{0}個參數:", getDateParamInfos.Length); foreach (ParameterInfo paramInfo in getDateParamInfos) { Console.WriteLine("參數名:{0},參數類型:{1}", paramInfo.Name, paramInfo.ParameterType.Name); } //獲取Add返回的數據類型 string getDateReturnType = getDate.ReturnType.Name; Console.WriteLine("GetDate返回的數據類型:{0}", getDateReturnType); Console.WriteLine("\n\n=============================================================="); Console.WriteLine("服務信息"); Console.WriteLine("服務名稱:{0},服務描述:{1}", sd.Services[0].Name, sd.Services[0].Documentation); Console.WriteLine("服務提供{0}個方法:", sd.PortTypes[0].Operations.Count); foreach (Operation op in sd.PortTypes[0].Operations) { Console.WriteLine("方法名稱:{0},方法描述:{1}", op.Name, op.Documentation); } Console.ReadKey(); }