65.9K
CodeProject 正在变化。 阅读更多。
Home

动态发现和调用 Web 服务

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.71/5 (34投票s)

2007年5月26日

CPOL

2分钟阅读

viewsIcon

168965

downloadIcon

3870

如何在不使用添加/Web引用的情况下调用Web服务

Screenshot - WsdlReader.jpg

引言

通常,当我们使用Web服务时,首先应该在Web引用中添加它,然后静态地调用其方法。 尽管速度很快,但它不够灵活。

为了通过动态调用Web服务来做到这一点,它具有非常好的灵活性。 例如,程序的源代码将被编译一次。

我们可以使用任何我们需要Web服务。 我们可以观察所有Web服务的方法和参数,自动分配方法和参数。

通常,程序员可以使用此方法完成任何工作。 像其他方法一样,在这种方法中,为了实现参数的灵活性,速度会降低。 但是花费的时间比获得的好处要多。

Using the Code

与Web服务通信的一种方法是设置。 通过WSDL文件提供有关Web服务的信息。 要完成这项工作,我们应该生成一个WebRequest并将其发送到WSDL。 有关各部分的所有活动均由WebRequest完成。

通过调用Web请求中的GetRequest方法,WebRequest将生成一个stream,该流将被发送到服务描述对象的read方法。 Read方法返回一个服务描述对象,该对象包含有关WSDL中Web服务的信息。 我们可以调用Web服务方法,了解Web的说明并使用代理类。

生成代理类的目标是制作类似于将放入*Reference.cs*的代码。 当用户在Visual Studio中添加Web引用并进行编译时,他/她可以通过应用程序中的程序集文件使用它。 第一步是制作一个服务描述导入器的实例,其目标是提供从WSDL读取信息并将其添加到codeDom.CodeCompilement的能力。 在生成服务描述导入器之后,我们调用add service。 Describe方法并将其发送到包含有关我们决定调用它的Web服务的信息的服务描述对象。 现在我们有了一个程序集文件,其方法和属性来自Web服务。 代理类中显示的所有方法都在主代码中的Web方法属性中。 这些类库具有一种方法,该方法从methodInfo返回一个对象数组到程序,我们可以从中选择一些方法并通过使用parameterInfo类来获取它们的参数。 为了调用Web方法,我们需要生成一个代理类的实例,该实例通过Activator,createinstance类提供Web服务信息的类型。

为了完成这项工作,我们应该将参数列表发送到Invoke方法,这是预期的。

private void DynamicInvocation()
{
Uri uri = new Uri(textBox1.Text);
WebRequest webRequest = WebRequest.Create(uri);
System.IO.Stream requestStream = webRequest.GetResponse().GetResponseStream();
// Get a WSDL file describing a service
ServiceDescription sd = ServiceDescription.Read(requestStream);
string sdName = sd.Services[0].Name;
// Initialize a service description servImport
ServiceDescriptionImporter servImport = new ServiceDescriptionImporter();
servImport.AddServiceDescription(sd, String.Empty, String.Empty);
servImport.ProtocolName = "Soap";
servImport.CodeGenerationOptions = CodeGenerationOptions.GenerateProperties;
CodeNamespace nameSpace = new CodeNamespace();
CodeCompileUnit codeCompileUnit = new CodeCompileUnit();
codeCompileUnit.Namespaces.Add(nameSpace);
// Set Warnings
ServiceDescriptionImportWarnings warnings = servImport.Import(nameSpace, codeCompileUnit);
if (warnings == 0)
{
StringWriter stringWriter = new StringWriter
	(System.Globalization.CultureInfo.CurrentCulture);
Microsoft.CSharp.CSharpCodeProvider prov = new Microsoft.CSharp.CSharpCodeProvider();
prov.GenerateCodeFromNamespace(nameSpace, stringWriter, new CodeGeneratorOptions());
// Compile the assembly with the appropriate references
string[] assemblyReferences = new string[2] 
	{ "System.Web.Services.dll", "System.Xml.dll" };
CompilerParameters param = new CompilerParameters(assemblyReferences);
param.GenerateExecutable = false;
param.GenerateInMemory = true;
param.TreatWarningsAsErrors = false;
param.WarningLevel = 4;
CompilerResults results = new CompilerResults(new TempFileCollection());
results = prov.CompileAssemblyFromDom(param, codeCompileUnit);
Assembly assembly = results.CompiledAssembly;
service = assembly.GetType(sdName);
methodInfo = service.GetMethods();
foreach (MethodInfo t in methodInfo)
{
if (t.Name == "Discover")
break;
 
treeWsdl.Nodes[0].Nodes.Add(t.Name);
}
treeWsdl.Nodes[0].Expand();
}
}

Wsdl 文件

在互联网上,您可以找到许多Web服务的wsdl文件,例如

谢谢

  • 感谢Faramaz Safi(我的老师)的指导
Screenshot - poem.jpg
© . All rights reserved.