gpt4 book ai didi

c# - 使用自定义类型通过 WSDL 反射(reflect) ASMX

转载 作者:太空宇宙 更新时间:2023-11-03 13:48:09 25 4
gpt4 key购买 nike

我需要通过 WSDL 反射(reflect) ASMX 网络服务。使用 this 的公认答案,简单的案例都很好.但是我在那里定义了一些复杂类型(强类型数据集)。服务的原始来源看起来像

[WebMethod]
public int GetCustomer(string civicRegistrationNo, out MyCompany.E_WebServices.DataSets.CustomerDataSet customerDS)

这个 CustomerDataSet 给我带来了麻烦,因为在反射中方法是这样的

GetCustomer [Int32]: civicRegistrationNo [String], customerDS [out XmlElement]

而我希望看到的(以及如果我直接反射(reflect) DLL 会出现什么)是

GetCustomer [Int32]: civicRegistrationNo [String], customerDS [out CustomerDataSet]

我应该如何改进我的代码(如下)以正确获取类型 CustomerDataSet(而不是 XmlElement)?肯定和WSDL中的这个block有关系

<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 引用,它只有 WSDL(我认为它不会直接转到该 DLL,即使它在同一台机器上),但是它可以很好地导出包含的类型。所以我认为这一定是可能的!? enter image description here

最佳答案

好吧,看来我成功了(也许不是最干净的方式)

string serviceUrl = "http://localhost/E-WebServices/WSCustomer.asmx";
var client = new WebClient();
ServiceDescription descr;
using (var stream = client.OpenRead(serviceUrl + "?wsdl"))
{
descr = ServiceDescription.Read(stream);
}
var importer = new ServiceDescriptionImporter()
{
ProtocolName = "Soap12",
Style = ServiceDescriptionImportStyle.Client,
CodeGenerationOptions = CodeGenerationOptions.GenerateProperties,
};
importer.AddServiceDescription(descr, null, null);
// Add any imported schemas
var importedSchemas = new List<string>();
foreach (XmlSchema wsdlSchema in descr.Types.Schemas)
{
foreach (XmlSchemaObject externalSchema in wsdlSchema.Includes)
{
if (externalSchema is XmlSchemaImport)
{
XmlSchemaImport schemaImport = externalSchema as XmlSchemaImport;
var split = schemaImport.Namespace.Split(new char[] { '/', '.' });
string schemaId = split[split.Count() - 2];
if (importedSchemas.Contains(schemaId))
continue;
importedSchemas.Add(schemaId);
Uri schemaUri = new Uri(serviceUrl + "?schema=" + schemaId);
XmlSchema schema;
using (var wsdlStream = client.OpenRead(schemaUri))
{
schema = XmlSchema.Read(wsdlStream, null);
}
importer.Schemas.Add(schema);
}
}
}
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");
Type t = service.GetType();
List<MethodInfo> methods = t.GetMethods().ToList();
// use them somehow
}

关于c# - 使用自定义类型通过 WSDL 反射(reflect) ASMX,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14571320/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com