当前位置:网站首页>Three ways to dynamically call WebService.Net
Three ways to dynamically call WebService.Net
2022-07-28 17:43:00 【Cang jiuxiao Hai】
Dynamic invocation webservice In three ways
Most of the time we go through " add to Web quote ..." How to create a client proxy class WebService, But in some cases, we may need to dynamically call an unknown service during the program running . stay .NET Framework Of System.Web.Services.Description There are things we need in the namespace .
Specific steps :
1. From the target URL download WSDL data .
2. Use ServiceDescription Create and format WSDL Document file .
3. Use ServiceDescriptionImporter Create a client proxy class .
4. Use CodeDom Dynamically create client proxy class assemblies .
5. Use reflection to call correlation WebService Method .
The above steps need to reference the following four namespaces :
using System.Web.Services.Description; //WS Description of
// The following are used to dynamically generate code based on the description and dynamically compile to get assemblies
using System.CodeDom;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
The above namespaces include the following important classes :
using System.Web.Services.Description Next :
ServiceDescription //WS describe
ServiceDescriptionImporter // Generate client proxy classes by description , Pay special attention to Style
Here are MSDN A description of it :
XML Web services The interface for is usually made up of Web Service description language (WSDL) Document to explain . for example , To get information about using http://localhost/service.asmx In public ASP.NET Of Web Service WSDL explain , Just navigate to http://localhost/service.asmx?WSDL. Use ServiceDescriptionImporter Class can easily put WSDL The information contained in the description is imported into the System.CodeDom.CodeCompileUnit object . Through adjustment Style The value of the parameter , Can indicate ServiceDescriptionImporter Instance to generate client agent class ( By calling this class transparently, you can provide Web Functions of services ) Or generate abstract classes ( This kind of encapsulation Web The function of a service without realizing it ). If you will Style Property is set to Client, be ServiceDescriptionImporter Generate client proxy class , By calling these classes to provide a description of Web Functions of services . If you will Style Property is set to Server, be ServiceDescriptionImporter Instances generate abstract classes , These classes represent the XML Web services Function without implementation . then , It can be implemented by writing classes that inherit from these abstract classes , And implement relevant methods .
using System.CodeDom Next :
CodedomUnit // It is used to set the namespace of dynamic code , Class name, etc. , Can pass ServiceDescriptionImporter.Import() Methods will WS The description code of is written to this class , For dynamic compilation
using System.CodeDom.Compiler Next :
CodedomProvider // Used to create and retrieve instances of code generators and code compilers , We mainly use its implementation subclasses CShareCodeProvider
It can be used directly CShareCodeProvider provider=new CShareCodeProvider() To generate , Or use CodedomProvider.CreateProvider("CSharp") To generate
ICodeCompiler // For compiling based on System.CodeDom Source code representation of .
It passes through CodedomProvider Of CreateCompiler() The method is to
CompilerResults // Represents the compilation result returned from the compiler . It consists of ICodeCompiler From the specified CodeCompileUnit It contains System.CodeDom Compile the assembly in the tree and return .CompiledAssembly Property indicates the compiled assembly .
After knowing the above information , Can be called dynamically WS 了 .
OK, Look at specific examples .
The target we want to call WebService, Its URL yes http://localhost:60436/Learn.WEB/WebService.asmx
HelloWorld.asmx
[WebService(Namespace = "http://www.rainsts.net/", Description=" my Web service ")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WebService : System.Web.Services.WebService {
public WebService () {
}
[WebMethod]
public string HelloWorld()
{
return "Hello Wolrd!";
}
}
1. Dynamic invocation WebService
Client dynamic call code
using System.IO;
using System.Net;
using System.Reflection;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Web.Services;
using System.Web.Services.Description;
using System.Web.Services.Protocols;
using System.Xml.Serialization;
// 1. Use WebClient download WSDL Information .
WebClient web = new WebClient();
Stream stream = web.OpenRead("http://localhost:60436/Learn.WEB/WebService.asmx?WSDL");
// 2. Create and format WSDL file .
ServiceDescription description = ServiceDescription.Read(stream);
// 3. Create a client proxy class .
ServiceDescriptionImporter importer = new ServiceDescriptionImporter();
importer.ProtocolName = "Soap"; // Specified access protocol .
importer.Style = ServiceDescriptionImportStyle.Client; // Generate client agent .
importer.CodeGenerationOptions = CodeGenerationOptions.GenerateProperties | CodeGenerationOptions.GenerateNewAsync;
importer.AddServiceDescription(description, null, null); // add to WSDL file .
// 4. Use CodeDom Compile the client proxy class .
CodeNamespace nmspace = new CodeNamespace(); // Add a namespace to the proxy class , The default is global space .
CodeCompileUnit unit = new CodeCompileUnit();
unit.Namespaces.Add(nmspace);
ServiceDescriptionImportWarnings warning = importer.Import(nmspace, unit);
CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
CompilerParameters parameter = new CompilerParameters();
parameter.GenerateExecutable = false;
parameter.GenerateInMemory = true;
parameter.ReferencedAssemblies.Add("System.dll");
parameter.ReferencedAssemblies.Add("System.XML.dll");
parameter.ReferencedAssemblies.Add("System.Web.Services.dll");
parameter.ReferencedAssemblies.Add("System.Data.dll");
CompilerResults result = provider.CompileAssemblyFromDom(parameter, unit);
// 5. Use Reflection call WebService.
if (!result.Errors.HasErrors)
{
Assembly asm = result.CompiledAssembly;
Type t = asm.GetType("WebService"); // If you added a namespace to the proxy class earlier , Here you need to add the namespace in front of the type .
object o = Activator.CreateInstance(t);
MethodInfo method = t.GetMethod("HelloWorld");
Console.WriteLine(method.Invoke(o, null));
}
2. Generate client agent assembly file
The above code creates a dynamic assembly in memory Formula completes the dynamic calling process . If we want to save the client agent class generated assembly file to the hard disk , The following modifications can be made . After generating the assembly file , We can go through Assembly.LoadFrom() Load and make reflection calls . For systems that require multiple calls , It is much more efficient than generating dynamic assemblies every time .
using System.IO;
using System.Net;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Web.Services;
using System.Web.Services.Description;
using System.Web.Services.Protocols;
using System.Xml.Serialization;
// 1. Use WebClient download WSDL Information .
WebClient web = new WebClient();
Stream stream = web.OpenRead("http://localhost:60436/Learn.WEB/WebService.asmx?WSDL");
// 2. Create and format WSDL file .
ServiceDescription description = ServiceDescription.Read(stream);
// 3. Create a client proxy class .
ServiceDescriptionImporter importer = new ServiceDescriptionImporter();
importer.ProtocolName = "Soap"; // Specified access protocol .
importer.Style = ServiceDescriptionImportStyle.Client; // Generate client agent .
importer.CodeGenerationOptions = CodeGenerationOptions.GenerateProperties | CodeGenerationOptions.GenerateNewAsync;
importer.AddServiceDescription(description, null, null); // add to WSDL file .
// 4. Use CodeDom Compile the client proxy class .
CodeNamespace nmspace = new CodeNamespace(); // Add a namespace to the proxy class , The default is global space .
CodeCompileUnit unit = new CodeCompileUnit();
unit.Namespaces.Add(nmspace);
ServiceDescriptionImportWarnings warning = importer.Import(nmspace, unit);
CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
CompilerParameters parameter = new CompilerParameters();
parameter.GenerateExecutable = false;
parameter.OutputAssembly = "test.dll"; // You can specify any file name you want .
parameter.ReferencedAssemblies.Add("System.dll");
parameter.ReferencedAssemblies.Add("System.XML.dll");
parameter.ReferencedAssemblies.Add("System.Web.Services.dll");
parameter.ReferencedAssemblies.Add("System.Data.dll");
CompilerResults result = provider.CompileAssemblyFromDom(parameter, unit);
if (result.Errors.HasErrors)
{
// Show compile error messages
}
Call assembly file demo
Assembly asm = Assembly.LoadFrom("test.dll");
Type t = asm.GetType("WebService");
object o = Activator.CreateInstance(t);
MethodInfo method = t.GetMethod("HelloWorld");
Console.WriteLine(method.Invoke(o, null));
3. Get the source code of the client proxy class
There is another situation , That is, we need to get the client proxy class C# Source code .
using System.IO;
using System.Net;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Web.Services;
using System.Web.Services.Description;
using System.Web.Services.Protocols;
using System.Xml.Serialization;
// 1. Use WebClient download WSDL Information .
WebClient web = new WebClient();
Stream stream = web.OpenRead("http://localhost:60436/Learn.WEB/WebService.asmx?WSDL");
// 2. Create and format WSDL file .
ServiceDescription description = ServiceDescription.Read(stream);
// 3. Create a client proxy class .
ServiceDescriptionImporter importer = new ServiceDescriptionImporter();
importer.ProtocolName = "Soap"; // Specified access protocol .
importer.Style = ServiceDescriptionImportStyle.Client; // Generate client agent .
importer.CodeGenerationOptions = CodeGenerationOptions.GenerateProperties | CodeGenerationOptions.GenerateNewAsync;
importer.AddServiceDescription(description, null, null); // add to WSDL file .
// 4. Use CodeDom Compile the client proxy class .
CodeNamespace nmspace = new CodeNamespace(); // Add a namespace to the proxy class , The default is global space .
CodeCompileUnit unit = new CodeCompileUnit();
unit.Namespaces.Add(nmspace);
ServiceDescriptionImportWarnings warning = importer.Import(nmspace, unit);
CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
// 5. Save source code to file . Of course , You can also save directly to the memory string .
TextWriter writer = File.CreateText("test.cs"); // Specify the source code file name you need .
provider.GenerateCodeFromCompileUnit(unit, writer, null);
writer.Flush();
writer.Close();
If you trigger "WebException: Cause of request HTTP state 415 Failure : Unsupported Media Type." Such anomalies , So congratulations, you are as depressed as me
, Hurry to the server WSE Turn it off . Must be used in WSE Under the circumstances , The client needs to be adjusted , As for the code, you need to write it yourself . ha-ha ~~~~
边栏推荐
- MySQL面试题大全(陆续更新)
- Visual Object Class介绍PASCAL VOC数据集
- 将input type='file' 类型的图片文件转成base64
- Ng repeat executes a method when iterating over the last element
- Using OCR to reverse recognize text content in airtest
- 分支与循环(for与do-while)
- Jerry ac692n --- prompt tone compression and modification
- easyui tree
- 小白如何零基础学习软件测试?
- 2021 National Undergraduate data statistics and Analysis Competition
猜你喜欢

2021 National Undergraduate data statistics and Analysis Competition

Solve package is not available (for R ve [package 'xxx' is not available (for R version x.y.z) "warning?]

mmcv安装的办法

Sed of shell programming

Kali installation configuration of penetration test killer

QT编写串口助手

JDWP未授权快速利用

Students' 20 R language exercises

解决Package is not available (for R ve【PACKAGE ‘XXX’ IS NOT AVAILABLE (FOR R VERSION X.Y.Z)” WARNING?】

.net动态调用webservice的三种方式
随机推荐
Mmcv installation method
Jdwp unauthorized rapid utilization
在airtest中使用ocr反向识别文本内容
小白必看的软件测试发展路线
学软件测试有用吗?
.net MVC的理解
How important is baseline safety from non child websites
软件测试前景如何?
PCA 报错Error in eigen(crossprod(t(X), t(X)), symmetric = TRUE) : ‘x‘里有无穷值或遗漏值
JVM性能调优
ionic中的$ionicPopup连续两个调用alert时需要注意的事项
Can you read the story?
软件测试培训机构可靠吗?
软件测试前景如何?该如何进行学习呢?
The difference between using switch in a loop and using break and continue after executing a condition
禅道项目管理软件,敏捷开发团队不可或缺的工具
解决Package is not available (for R ve【PACKAGE ‘XXX’ IS NOT AVAILABLE (FOR R VERSION X.Y.Z)” WARNING?】
【C语言进阶】——剖析入微数据在内存中的存储 【下】(浮点数存储)
Solve package is not available (for R ve [package 'xxx' is not available (for R version x.y.z) "warning?]
Talking about test platform -- Discussion on construction mode