我们在C#Batch应用程序中连接多个(20-30)第三方Web服务。我们正在尝试动态调用这些Web服务的最佳方法(不生成代理或使用wsdl)。将在数据库表中配置所有第三方代理端点或URL。客户端应用程序将在运行时检查URL并进行服务调用。我们并不担心异步调用它是所有同步过程。
SQL表:客户端配置
Client URL Method IsActive
A http://serverhost/ClientA/Service1.svc Submit 1
B http://serverhost/ClientB/Service2.asmx Submit 1
唯一的问题是我们不确定第三方服务实现是WCF还是asmx。我在线阅读了一些文章,使用HttpWebRequest动态调用Web服务(不生成代理/ wsdl。) 这是实现这个或我需要考虑的任何问题的最佳方式吗?
请参见下文ex:
public static void CallWebService(string xml)
{
var _Url = "http://serverhost/ClientA/Service1.svc";
var _action = "http://serverhost/ClientA/Service1.svc/Submit";
try
{
ASCIIEncoding encoder = new ASCIIEncoding();
byte[] data = encoder.GetBytes(xml);
XmlDocument soapEnvelopeXml = CreateSoapEnvelope(xml);
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(_Url);
webRequest.Headers.Add("SOAPAction", _action);
webRequest.ContentType = "text/xml;charset=\"utf-8\"";
webRequest.ContentLength = data.Length;
webRequest.Accept = "text/xml";
webRequest.Method = "POST";
Stream webStream = webRequest.GetRequestStream();
webStream.Write(data, 0, data.Length);
webStream.Close();
WebResponse response = webRequest.GetResponse();
Stream responseStream = response.GetResponseStream();
using (StreamReader sr = new StreamReader(responseStream))
{
string s = sr.ReadToEnd();
}
}
catch (Exception ex)
{
responseStream = ex.Response.GetResponseStream();
}
}
Here is the details shared by one of the client.
http://setup.localhost.com/ClientA/Service1.asmx
Operation : Submit
SOAP 1.1
The following is a sample SOAP 1.1 request and response. The placeholders shown need to be
replaced with actual values.
POST /ClientA/Service1.asmx HTTP/1.1
Host: setup.localhost.com
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://setup.localhost.com/Submit"
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<Submit xmlns="http://setup.localhost.com/">
<eCitXML>string</eCitXML>
<eCitPdf>base64Binary</eCitPdf>
<eCitKey>string</eCitKey>
</Submit>
</soap:Body>
</soap:Envelope>
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<SubmitResponse xmlns="http://setup.localhost.com/">
<SubmitResult>string</SubmitResult>
</SubmitResponse>
</soap:Body>
</soap:Envelope>
SOAP 1.2
The following is a sample SOAP 1.2 request and response. The placeholders shown need to be
replaced with actual values.
POST /ClientA/Service1.asmx HTTP/1.1
Host: setup.localhost.com
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length
<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-
envelope">
<soap12:Body>
<Submit xmlns="http://setup.localhost.com/">
<eCitXML>string</eCitXML>
<eCitPdf>base64Binary</eCitPdf>
<eCitKey>string</eCitKey>
</Submit>
</soap12:Body>
</soap12:Envelope>
HTTP/1.1 200 OK
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length
<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-
envelope">
<soap12:Body>
<SubmitResponse xmlns="http://setup.localhost.com/">
<SubmitResult>string</SubmitResult>
</SubmitResponse>
</soap12:Body>
</soap12:Envelope>
答案 0 :(得分:0)
我认为你的问题可以改写为
除了SOAP操作和URL之外,是否存在调用任何SOAP 1.1或1.2 Web服务操作而不事先了解服务操作的通用方法?
我假设所有第三方Web服务都公开了一个接受并返回相同类型的公共操作。
如果是这种情况,那么为您提供正确的服务操作合同建模,您可以使用ChannelFactory来调用所有服务。
以这种方式调用WCF服务straightforward,但要调用asmx服务,您需要执行bit more work。因此,您的客户端代码需要知道服务是asmx还是wcf,而且,如果是wcf,服务是否为soap 1.1或1.2。
我必须说,一旦你实现了这个目标,我就会努力去理解你将拥有什么样的优势。如果您拥有所有20多个服务,我可以看到价值,但事实并非如此。
当然,你不会有大量令人讨厌的生成服务引用代码,但WSDL的全部意义在于它允许机器生成的服务契约。如果第三方服务进行任何重大更改,您需要在客户端代码中手动同步这些更改,而不仅仅是重新生成客户端。