动态调用多个WCF和asmx Web服务,而无需生成代理或使用WSDL

时间:2014-10-16 03:00:52

标签: web-services wcf wsdl

我们在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>

1 个答案:

答案 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的全部意义在于它允许机器生成的服务契约。如果第三方服务进行任何重大更改,您需要在客户端代码中手动同步这些更改,而不仅仅是重新生成客户端。