这绝对是可能的......而且不太复杂。您只需要添加一些不同的技术即可。您可以使用“描述导入器”在运行时导入服务描述。关联
我所做的基本上是创建以下步骤:
1)使用阅读器获取WSDL文件(本地或远程,不同的方法)
XmlTextReader myXmlReader;
myWebService = new WebServiceImporterCompiler(WSDLPath, soapVersion);
if (useLocalWSDL)
{
FileWebRequest wr = (FileWebRequest)FileWebRequest.Create(WSDLPath);
FileWebResponse wres = (FileWebResponse)wr.GetResponse();
myXmlReader = new XmlTextReader(wres.GetResponseStream());
}
else
{
Uri uri = new Uri(WSDLPath); //WEBSERVICE URI
HttpWebRequest wr = (HttpWebRequest)HttpWebRequest.Create(uri.OriginalString + "?wsdl");
wr.Credentials = wr.Credentials = new NetworkCredential(userName, password ?? "");
HttpWebResponse wres = (HttpWebResponse)wr.GetResponse();
myXmlReader = new XmlTextReader(wres.GetResponseStream());
}
Run Code Online (Sandbox Code Playgroud)
2) 从定义 / myXmlReader 构建程序集
检查xml是否可读
if (!System.Web.Services.Description.ServiceDescription.CanRead(myXmlReader))
{
throw new IOException("WSDL not readable");
}
Run Code Online (Sandbox Code Playgroud)
使用一些基本选项加载导入器(您可以在此处添加/更改某些内容)我创建一个程序集(dll),但使用开关参数。GenerateInMemory您将能够生成内存中类。
ServiceDescriptionImporter descriptionImporter = new ServiceDescriptionImporter();
ServiceDescription serviceDescription = ServiceDescription.Read(myXmlReader);
descriptionImporter.ProtocolName = soapVersion.ToString(); // EITHER SOAP OR SOAP12
descriptionImporter.AddServiceDescription(serviceDescription, null, null);
descriptionImporter.Style = ServiceDescriptionImportStyle.Client;
descriptionImporter.CodeGenerationOptions = System.Xml.Serialization.CodeGenerationOptions.GenerateProperties;
Run Code Online (Sandbox Code Playgroud)
使用 CodeDomProvider 编译程序集
CodeCompileUnit codeUnit = new CodeCompileUnit();
CodeNamespace codeNamespace = new CodeNamespace();
codeUnit.Namespaces.Add(codeNamespace); // Add additional Namespaces
ServiceDescriptionImportWarnings importWarnings = descriptionImporter.Import(codeNamespace, codeUnit);
if (importWarnings == 0)
{
using (CodeDomProvider compiler = CodeDomProvider.CreateProvider("CSharp"))
{
string[] references = { "System.dll", "System.Web.Services.dll", "System.Xml.dll" };
CompilerParameters parameters = new CompilerParameters(references);
parameters.GenerateExecutable = false;
parameters.GenerateInMemory = false;
parameters.IncludeDebugInformation = false;
parameters.CompilerOptions = "/optimize";
parameters.TempFiles = new TempFileCollection(System.IO.Path.GetTempPath() + "xxx", false);
parameters.ReferencedAssemblies.Add("System.dll");
results = compiler.CompileAssemblyFromSource(parameters, CSharpCode);
foreach (CompilerError cError in results.Errors)
{
// log errors
}
if (results.Errors.Count > 0 || results.CompiledAssembly == null) throw new Exception("Kompilierfehler bei Assemblyerstellung");
}
}
Run Code Online (Sandbox Code Playgroud)
3) 使用生成的汇编对象来调用方法,例如调用服务
public T InvokeMethod <T>(Assembly assembly, string serviceNameToCall, MethodInfo methodToCall)
{
SoapHttpClientProtocol mySoapProtocoll;
try
{
object serviceInstance = myAssembly.CreateInstance(serviceNameToCall);
mySoapProtocoll = (SoapHttpClientProtocol)serviceInstance;
mySoapProtocoll.Credentials = CredentialCache.DefaultCredentials; // or use your own
object myObject = (T)ServiceType.InvokeMember(methodToCall, BindingFlags.InvokeMethod, null, mySoapProtocoll, args);
}
}
Run Code Online (Sandbox Code Playgroud)
要获取 methodInfo 对象/可用方法,请使用反射来迭代程序集/类。
可以在此处找到有关反射的完整指南