看到很多动态调用WebService都只是动态调用地址而已
webservice还是同一个才行
如果换另外的一个不同的webservice
则需重新生成代理类
下面的例子
稍加修改可以做到只修改配置文件而适应不同的webservice
主要原理是根据指定的WebService地址的WSDL
然后解析模拟生成一个代理类
通过反射调用里面的方法
具体看代码
下面是WebService代码
using System;
using SystemCollectionsGeneric;
using SystemLinq;
using SystemWeb;
using SystemWebServices;
namespace TestWebService
{
/// <summary>
/// Service 的摘要说明
/// </summary>
[WebService(Namespace = Description = 我的Web服务)]
[WebServiceBinding(ConformsTo = WsiProfilesBasicProfile_)]
[SystemComponentModelToolboxItem(false)]
// 若要允许使用 ASPNET AJAX 从脚本中调用此 Web 服务请取消对下行的注释
// [SystemWebScriptServicesScriptService]
public class TestWebService : SystemWebServicesWebService
{
[WebMethod]
public string HelloWorld()
{
return 测试Hello World;
}
[WebMethod]
public string Test()
{
return 测试Test;
}
[WebMethod(CacheDuration = Description = 测试)]
public List<String> GetPersons()
{
List<String> list = new List<string>();
listAdd(测试一);
listAdd(测试二);
listAdd(测试三);
return list;
}
}
}
下面是客户端的代码
客户端:
using System;
using SystemIO;
using SystemCollectionsGeneric;
using SystemLinq;
using SystemCollections;
using SystemWeb;
using SystemNet;
using SystemReflection;
using SystemCodeDom;
using SystemCodeDomCompiler;
using SystemWebServices;
using SystemText;
using SystemWebServicesDescription;
using SystemWebServicesProtocols;
using SystemXmlSerialization;
using SystemWindowsForms;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
WebClient client = new WebClient();
String url = ;//这个地址可以写在Config文件里面这里取出来就行了在原地址后面加上 ?WSDL
Stream stream = clientOpenRead(url);
ServiceDescription description = ServiceDescriptionRead(stream);
ServiceDescriptionImporter importer = new ServiceDescriptionImporter();//创建客户端代理代理类
importerProtocolName = Soap; //指定访问协议
importerStyle = ServiceDescriptionImportStyleClient; //生成客户端代理
importerCodeGenerationOptions = CodeGenerationOptionsGenerateProperties | CodeGenerationOptionsGenerateNewAsync;
importerAddServiceDescription(description null null); //添加WSDL文档
CodeNamespace nmspace = new CodeNamespace(); //命名空间
nmspaceName = TestWebService;
CodeCompileUnit unit = new CodeCompileUnit();
unitNamespacesAdd(nmspace);
ServiceDescriptionImportWarnings warning = importerImport(nmspace unit);
CodeDomProvider provider = CodeDomProviderCreateProvider(CSharp);
CompilerParameters parameter = new CompilerParameters();
parameterGenerateExecutable = false;
parameterOutputAssembly = MyTestdll;//输出程序集的名称
parameterReferencedAssembliesAdd(Systemdll);
parameterReferencedAssembliesAdd(SystemXMLdll);
parameterReferencedAssembliesAdd(SystemWebServicesdll);
parameterReferencedAssembliesAdd(SystemDatadll);
CompilerResults result = providerCompileAssemblyFromDom(parameter unit);
if (resultErrorsHasErrors)
{
// 显示编译错误信息
}
Assembly asm = AssemblyLoadFrom(MyTestdll);//加载前面生成的程序集
Type t = asmGetType(TestWebServiceTestWebService);
object o = ActivatorCreateInstance(t);
MethodInfo method = tGetMethod(GetPersons);//GetPersons是服务端的方法名称你想调用服务端的什么方法都可以在这里改最好封装一下
String[] item = (String[])methodInvoke(o null);
//注methodInvoke(o null)返回的是一个Object如果你服务端返回的是DataSet这里也是用(DataSet)methodInvoke(o null)转一下就行了methodInvoke(null)这里的null可以传调用方法需要的参数string[]形式的
foreach (string str in item)
ConsoleWriteLine(str);
//上面是根据WebService地址模似生成一个代理类如果你想看看生成的代码文件是什么样子可以用以下代码保存下来默认是保存在bin目录下面
TextWriter writer = FileCreateText(MyTestcs);
providerGenerateCodeFromCompileUnit(unit writer null);
writerFlush();
writerClose();
}
}
}