我需要通过 WSDL 反映 ASMX Web 服务。使用this的公认答案,简单的情况一切正常。但是我在那里定义了一些复杂类型(强类型数据集)。服务的原始来源看起来像
[WebMethod]
public int GetCustomer(string civicRegistrationNo, out MyCompany.E_WebServices.DataSets.CustomerDataSet customerDS)
这CustomerDataSet
给我带来了麻烦,因为在反射中方法是
GetCustomer [Int32]: civicRegistrationNo [String], customerDS [out XmlElement]
而我想看到的(如果我直接反映 DLL 会出现什么)是
GetCustomer [Int32]: civicRegistrationNo [String], customerDS [out CustomerDataSet]
我应该如何改进我的代码(如下)以使类型CustomerDataSet
正确(而不是 as XmlElement
)?当然它与 WSDL 中的这个块有关
<s:import namespace="http://tempuri.org/CustomerDataSet.xsd"/>
<s:import schemaLocation="http://localhost/E-WebServices/WSCustomer.asmx?schema=CustomerDataSet" namespace="http://tempuri.org/CustomerDataSet.xsd"/>
是的,如果我打开,我可以在浏览器中看到该定义
http://localhost/E-WebServices/WSCustomer.asmx?schema=CustomerDataSet
但是如何从下面的代码中获取它?
var client = new System.Net.WebClient();
var stream = client.OpenRead("http://localhost/E-WebServices/WSCustomer.asmx?wsdl");
var description = ServiceDescription.Read(stream);
var importer = new ServiceDescriptionImporter();
importer.ProtocolName = "Soap12";
importer.AddServiceDescription(description, null, null);
importer.Style = ServiceDescriptionImportStyle.Client;
importer.CodeGenerationOptions = CodeGenerationOptions.GenerateProperties;
var nmspace = new CodeNamespace();
var unit1 = new CodeCompileUnit();
unit1.Namespaces.Add(nmspace);
var warning = importer.Import(nmspace, unit1);
if (warning == 0)
{
CodeDomProvider provider1 = CodeDomProvider.CreateProvider("CSharp");
string[] assemblyReferences = new string[5] { "System.dll", "System.Web.Services.dll", "System.Web.dll", "System.Xml.dll", "System.Data.dll" };
CompilerParameters parms = new CompilerParameters(assemblyReferences);
CompilerResults results = provider1.CompileAssemblyFromDom(parms, unit1);
if (results.Errors.Count > 0)
{
foreach (CompilerError oops in results.Errors)
Debug.WriteLine(oops.ErrorText);
throw new Exception("Compile Error Occured calling webservice");
}
object service = results.CompiledAssembly.CreateInstance("WSCustomer");
List<MethodInfo> methods = service.GetType().GetMethods().ToList();
// use them somehow
}
我受到 Visual Studio 本身所做的事情的启发——如果添加了 web ref,它只有 WSDL(我认为,即使它在同一台机器上,它也不会直接转到那个 DLL),但它可以派生包含的类型很好。所以我认为这一定是可能的!?