ASP Core添加WCF Service遇WSDL导入错误及XML生成求助
问题求助:ASP Core中WSDL导入错误及XML生成方案
一、WSDL导入错误详情
添加WCF Service时触发以下错误:
"Cannot import wsdl:port
Detail: There was an error importing a wsdl:binding that the wsdl:port is dependent on.
XPath to wsdl:binding: //wsdl:definitions[@targetNamespace=':binding[@name='AAResWebServicesHttpBinding']"
我们的需求是生成指定格式的SOAP请求XML,示例如下:
<?xml version="1.0" encoding="UTF-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soap:Header> <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soap:mustUnderstand="1"> <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="XXXX"> <wsse:Username>XXX</wsse:Username> <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">XXXX</wsse:Password> </wsse:UsernameToken> </wsse:Security> </soap:Header> <soap:Body xmlns:ns1="http://www.opentravel.org/OTA/2003/05"> <ns1:OTA_AirAvailRQ EchoToken="11868765275150-1300257933" PrimaryLangID="en-us" SequenceNmbr="1" TimeStamp="2012-08-27T03:00:23" Version="20061.00" Target="TEST"> <ns1:POS> <ns1:Source TerminalID="XXXX"> <ns1:RequestorID ID="XXXX" Type="XXXX" /> <ns1:BookingChannel Type="12" /> </ns1:Source> </ns1:POS> <ns1:OriginDestinationInformation> <ns1:DepartureDateTime WindowAfter="P1D" WindowBefore="P1D">2023-01-20T10:00:00</ns1:DepartureDateTime> <ns1:OriginLocation LocationCode="BOM" /> <ns1:DestinationLocation LocationCode="SHJ" /> </ns1:OriginDestinationInformation> <ns1:OriginDestinationInformation> <ns1:DepartureDateTime WindowAfter="P1D" WindowBefore="P1D">2023-01-25T10:00:00</ns1:DepartureDateTime> <ns1:OriginLocation LocationCode="SHJ" /> <ns1:DestinationLocation LocationCode="BOM" /> </ns1:OriginDestinationInformation> <ns1:TravelerInfoSummary> <ns1:AirTravelerAvail> <ns1:PassengerTypeQuantity Code="ADT" Quantity="3" /> <ns1:PassengerTypeQuantity Code="CHD" Quantity="1" /> </ns1:AirTravelerAvail> </ns1:TravelerInfoSummary> </ns1:OTA_AirAvailRQ> </soap:Body> </soap:Envelope>
二、直接生成XML的错误
跳过WSDL引用手动生成XML时,收到服务端错误:
WSS4JInHandler: Request does not contain required Security header
排查确认需要添加WSSE安全头,但资料显示需先导入WSDL才能配置该头。
解决方案
方案1:修复WSDL导入错误
- 补全WSDL命名空间:错误信息里的
@targetNamespace='明显缺失内容,大概率是WSDL文件在保存/传输时丢失了命名空间值,手动打开WSDL文件,找到definitions节点的targetNamespace属性,补全正确的命名空间后重新导入。 - 用SvcUtil手动生成代理:避开VS自动导入的问题,打开开发者命令提示符执行以下命令,生成代理类和配置文件:
把生成的svcutil.exe /language:C# /out:AirAvailService.cs /config:App.config 你的WSDL地址或本地路径AirAvailService.cs加入项目,手动修改App.config里的绑定配置,添加WSSE安全验证相关参数。 - 检查绑定兼容性:ASP Core对WCF旧绑定支持有限,确认WSDL里的
AAResWebServicesHttpBinding是否为标准WSHttpBinding,如果是自定义绑定,需在代码里手动配置绑定的安全模式、消息版本等参数。
方案2:手动生成符合要求的XML
如果不想依赖WSDL代理,直接用C#构造完整的SOAP请求XML,包含WSSE安全头:
using System.Xml; using System.Xml.Linq; using System; using System.IO; public string GenerateAirAvailRequest(string username, string password, string requestorId, string terminalId) { // 定义所有需要的命名空间 XNamespace soapNs = "http://schemas.xmlsoap.org/soap/envelope/"; XNamespace wsseNs = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"; XNamespace wsuNs = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"; XNamespace otaNs = "http://www.opentravel.org/OTA/2003/05"; // 构造WSSE安全头 var securityHeader = new XElement(wsseNs + "Security", new XAttribute(soapNs + "mustUnderstand", "1"), new XElement(wsseNs + "UsernameToken", new XAttribute(wsuNs + "Id", $"UsernameToken-{Guid.NewGuid()}"), new XElement(wsseNs + "Username", username), new XElement(wsseNs + "Password", new XAttribute("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText"), password))); // 构造OTA请求体 var otaBody = new XElement(otaNs + "OTA_AirAvailRQ", new XAttribute("EchoToken", Guid.NewGuid().ToString()), new XAttribute("PrimaryLangID", "en-us"), new XAttribute("SequenceNmbr", "1"), new XAttribute("TimeStamp", DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss")), new XAttribute("Version", "20061.00"), new XAttribute("Target", "TEST"), new XElement(otaNs + "POS", new XElement(otaNs + "Source", new XAttribute("TerminalID", terminalId), new XElement(otaNs + "RequestorID", new XAttribute("ID", requestorId), new XAttribute("Type", "1")), new XElement(otaNs + "BookingChannel", new XAttribute("Type", "12")))), new XElement(otaNs + "OriginDestinationInformation", new XElement(otaNs + "DepartureDateTime", new XAttribute("WindowAfter", "P1D"), new XAttribute("WindowBefore", "P1D"), "2023-01-20T10:00:00"), new XElement(otaNs + "OriginLocation", new XAttribute("LocationCode", "BOM")), new XElement(otaNs + "DestinationLocation", new XAttribute("LocationCode", "SHJ"))), new XElement(otaNs + "OriginDestinationInformation", new XElement(otaNs + "DepartureDateTime", new XAttribute("WindowAfter", "P1D"), new XAttribute("WindowBefore", "P1D"), "2023-01-25T10:00:00"), new XElement(otaNs + "OriginLocation", new XAttribute("LocationCode", "SHJ")), new XElement(otaNs + "DestinationLocation", new XAttribute("LocationCode", "BOM"))), new XElement(otaNs + "TravelerInfoSummary", new XElement(otaNs + "AirTravelerAvail", new XElement(otaNs + "PassengerTypeQuantity", new XAttribute("Code", "ADT"), new XAttribute("Quantity", "3")), new XElement(otaNs + "PassengerTypeQuantity", new XAttribute("Code", "CHD"), new XAttribute("Quantity", "1"))))); // 组装完整SOAP信封 var envelope = new XElement(soapNs + "Envelope", new XAttribute(XNamespace.Xmlns + "soap", soapNs), new XAttribute(XNamespace.Xmlns + "xsd", "http://www.w3.org/2001/XMLSchema"), new XAttribute(XNamespace.Xmlns + "xsi", "http://www.w3.org/2001/XMLSchema-instance"), new XElement(soapNs + "Header", securityHeader), new XElement(soapNs + "Body", new XAttribute(XNamespace.Xmlns + "ns1", otaNs), otaBody)); // 生成格式化的XML字符串 using var stringWriter = new StringWriter(); using var xmlWriter = XmlWriter.Create(stringWriter, new XmlWriterSettings { Indent = true, OmitXmlDeclaration = false }); envelope.WriteTo(xmlWriter); xmlWriter.Flush(); return stringWriter.ToString(); }
调用这个方法就能生成符合要求的XML,发送请求时设置Content-Type为text/xml; charset=utf-8即可,无需依赖WSDL代理。
内容的提问来源于stack exchange,提问作者Yousif
相关产品推荐
相关产品推荐

