2

这是我目前的情况。我不得不打破如何进行 Web 服务调用的标准。我们有 60 多个 WSDL 可以连接,并且名称会根据参数进行更改。我使用 WebClient 动态创建了 Web 服务调用并手动构建了信封(决定这样做而不是由上层管理人员添加每个 Web 服务)。我得到一个字符串响应,其中包含与 XSD 匹配的有效 XML。我试图弄清楚如何创建一个类来动态引用字段而不是每个 WSDL 的类(基于所使用的 XSD 构建一个类)。这是我正在做的事情:

public string results;

using (WebClient client = new WebClient())
{
    string soapENV = @"http://schemas.xmlsoap.org/soap/envelope/";
    var payload = @"<?xml version=""1.0"" encoding=""utf-8""?>" +
                   "<SOAP-ENV:Envelope xmlns:SOAP-ENV='" + soapENV + "'>" +
                     "<SOAP-ENV:Header/>" + 
                       "<SOAP-ENV:Body>" + 
                         "<" + myParams.requestName + " xmlns='" +    
                             myParams.requestNamespace + "'>" +
                           "<MtvnSvcVer>1.0</MtvnSvcVer>" + 
                           "<MsgUUID>" + UUID + "</MsgUUID>" + 
                           "<PrcsParms>" + 
                           "<SrcID>" + currentVendorID + "</SrcID>" + 
                           "</PrcsParms>"
                           ................
                       "</SOAP-ENV:Body>" + 
                     "</SOAP-ENV:Envelope>";
   this.results = client.UploadString  (URL, payload);
}

为了节省时间和空间,我取出了一些 XML 标签。XSD 响应具有与上述相同的 XML 标记值。然后我调用它来执行如下:

string results = connectwareService.InvokeConnectWare();

返回的结果如下所示:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Body>        
    <DPNmeAddrInqMtvnSvcRes  xmlns="mtvnCWDPNmeAddrInqSvcRes"> 
     <MtvnSvcVer>1.0</MtvnSvcVer>
     <MsgUUID>DATA HERE</MsgUUID>           
      <Svc>
       <SvcParms>
         <ApplID>DATA HERE</ApplID>
         <SvcID>DATA HERE</SvcID>
         <SvcVer>1.0</SvcVer>
         <RqstUUID>DATA HERE</RqstUUID>
       </SvcParms>
       <MsgData>
       <DPNmeAddrInqResData xmlns="mtvnCWDPNmeAddrInqResData">
         <E20007>DATA HERE</E20007>
        ........    
   </soapenv:Body> 
</soapenv:Envelope>

代码中有没有办法做到这一点?我一直看到人们提到使用 xsd.exe。可以在后面的代码中执行吗?我在想我可以通读并填充一个通用类,其中标签名称作为名称,数据作为值作为最后的手段,但必须有一种方法可以在代码中动态生成它。我想我可以做的另一种方法是读取所有 60 多个 wsdls 并运行 xsd.exe 来构建所需的类?

另外,仅供参考 - 我正在将旧的 Cold Fusion 代码转换为 C#,并且我正在尝试找出如何替换其“ConvertXmlToStruct”方法。任何帮助将不胜感激。

4

2 回答 2

3

xsd.exe 仅运行一次以构建代表 XSD 中定义的对象的类文件。然后,您使用 XmlSerializer 类将 XML 实际转换(也称为反序列化)到 c# 类。

那里有很多关于在 C# 中反序列化 XML 的链接:

如何在 C# 中使用 xsd?

http://msdn.microsoft.com/en-us/library/ms950721.aspx

于 2013-01-31T19:21:29.367 回答
2

XSD.exe 工作得很好。请查看我在下面使用的代码以使其工作:

Process process = new Process();
        string arguments = @" " + row["OutputFileDirectory"].ToString() + row["XSDMainBuildName"].ToString() + " " + row["OutputFileDirectory"].ToString() + row["ImportNames"].ToString() + " /c /language:CS /out:" + row["OutputClassDirectory"].ToString() + " /namespace:" + row["Namespace"].ToString();
        string fileNameXSD = "";
        if (Directory.Exists(@"C:\Program Files (x86)\Microsoft SDKs\Windows\v6.0A\bin"))
        {
            fileNameXSD = @"C:\Program Files (x86)\Microsoft SDKs\Windows\v6.0A\bin\xsd.exe";
        }
        else
        {
            fileNameXSD = @"C:\Program Files\Microsoft.NET\SDK\v2.0\Bin\xsd.exe";
        }
        process.StartInfo.Arguments = arguments;
        process.StartInfo.FileName = fileNameXSD;
        process.StartInfo.UseShellExecute = false;
        process.StartInfo.RedirectStandardError = true;
        process.StartInfo.RedirectStandardOutput = true;
        process.Start();
        string output = process.StandardOutput.ReadToEnd();
        string error = process.StandardError.ReadToEnd();
        if (!DataValidator.ValidateFieldIsBlank(error))
        {
            lblOutputResults.Text = error;
        }
        process.WaitForExit();
        process.Close();

这是放在我的网络表单后面的代码中的。这样做是为我选择构建的每个项目启动 xsd.exe 进程。这帮助我们公司解决了很多问题。感谢所有帮助并提供更多信息的人。

于 2013-05-13T12:53:51.260 回答