Tuesday, October 14, 2008

A userful Webservice class file!

We want to share some useful web service help Charp class. You can use this class to dynamically call web service!
Dynamic call webservice can be divided into following steps:
1. download WSDL from given URL.
2. create and formate WSDL by using ServiceDescription class.
3. create client proxy class by using ServiceDescriptionImporter class.
4. dynamic create program enviroment for client proxy class by using CodeDom class.
5. invoke web service by using class reflection.
The source can be illustrated as WebServiceHelper class:
using System;using System.Data;using System.Configuration;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;using System.CodeDom.Compiler;using System.Net;using System.CodeDom;using System.IO;using System.Collections.Generic;using System.Reflection;using Microsoft.CSharp;using System.Web.Services;using System.Web.Services.Protocols;using System.Web.Services.Description;using System.Xml.Serialization;
namespace WebServiceTest{ public class WebServiceHelper { static SortedList typeList = new SortedList(); static string getCachedKey(string url, string className) { return url.ToLower()+className; } static Type getTypeFromCash(string url, string className) { string myKey = getCachedKey(url,className); foreach(KeyValuePair pair in typeList) { if (myKey == pair.Key) { return pair.Value; } } return null; } static Type getTypeFromWebService(string url, string className) { //string @namespace = “WebServiceTest”; url = getUrl(url); if ((className == null) (className == “”)) { className = getWSClassName(url); }
//1. using webclient to download wsdl WebClient webClient = new WebClient(); Stream stream = webClient.OpenRead(url + “?WSDL”);
//2. create and serialize wsdl document ServiceDescription description = ServiceDescription.Read(stream);
//3. create client proxy class ServiceDescriptionImporter importer = new ServiceDescriptionImporter();
importer.ProtocolName = “SOAP”; //assign transport protocol importer.Style = ServiceDescriptionImportStyle.Client; //create client proxy importer.CodeGenerationOptions = CodeGenerationOptions.GenerateProperties CodeGenerationOptions.GenerateNewAsync; importer.AddServiceDescription(description, null, null); //add WSDL document
//4. using CodeDom compile proxy class CodeNamespace nmspace = new CodeNamespace(); //You can define namespace for the proxy. Defalt is global. CodeCompileUnit unit = new CodeCompileUnit(); unit.Namespaces.Add(nmspace);
ServiceDescriptionImportWarnings warning = importer.Import(nmspace, unit); CodeDomProvider provider = CodeDomProvider.CreateProvider(”CSharp”);
CompilerParameters parameters = new CompilerParameters(); parameters.GenerateExecutable = false; parameters.GenerateInMemory = true; parameters.ReferencedAssemblies.Add(”System.dll”); parameters.ReferencedAssemblies.Add(”System.XML.dll”); parameters.ReferencedAssemblies.Add(”System.Web.Services.dll”); parameters.ReferencedAssemblies.Add(”System.Data.dll”); CompilerResults result = provider.CompileAssemblyFromDom(parameters, unit); if(true == result.Errors.HasErrors) { System.Text.StringBuilder sb = new System.Text.StringBuilder(); foreach(CompilerError ce in result.Errors) { sb.Append(ce.ToString()); sb.Append(Environment.NewLine); } throw new Exception(sb.ToString()); } Assembly assembly = result.CompiledAssembly; Type t = assembly.GetType(className); return t; } public static object invokeWebService(string url,string methodName, object[] args) { return invokeWebService(url,null,methodName,args); } public static object invokeWebService(string url, string className, string methodName, object[] args) { try { Type t = getTypeFromCash(url, className); if(t==null) { t = getTypeFromWebService(url,className); string key = getCachedKey(url,className); typeList.Add(key,t); }
object obj = Activator.CreateInstance(t); MethodInfo mi = t.GetMethod(methodName); return mi.Invoke(obj,args); } catch(Exception ex) { throw new Exception(ex.InnerException.Message,new Exception(ex.InnerException.StackTrace)); } } static string getWSClassName(string url) { string[] parts = url.Split(’/'); string[] pps = parts[parts.Length - 1].Split(’.'); return pps[0]; } static string getUrl(string url) { //url = url + “?WSDL”; int wsdlPosition = url.ToUpper().IndexOf(”?WSDL”); if ( wsdlPosition != -1) { return url.Substring(0,wsdlPosition); } return url; } }}You can import this class into your project and test it by following code:
string url = “http://www.webservicex.net/globalweather.asmx“;
string[] args = new string[2];
args[0]=”Chongqing”;
args[1]=”China”;
object result = WebServiceHelper. InvokeWebService(url, “GetWeather”,args);
Console.Writeline(”The result is %s”, result.toString());

No comments: