我们有一个ASP.NET Core系统,我们需要使用SOAP连接到另一个Web服务(我们收到了客户的WSDL)。
在过去,我们应该使用Visual Studio中的WCF选项使用“添加服务引用”。
对于dotnet核心项目,选项不再可用,但有几个选项可以获得相同的解决方案:
在命令行中使用SvcUtil或在此处安装插件https://blogs.msdn.microsoft.com/webdev/2016/06/26/wcf-connected-service-for-net-core-1-0-0-and-asp-net-core-1-0-0-is-now-available/以生成.cs文件
这两种解决方案都需要与这些nuget包https://github.com/dotnet/wcf一起使用
所以我的问题是:除了使用WCF在C#中访问SOAP服务之外,还有另一种解决方案吗?
您可以使用Soap UI之类的工具来获取xml请求的实际格式。
然后,您可以使用WebRequest执行请求 - 类似下面的代码。据我所知,没有办法自动生成类,所以你必须自己进行反序列化:
public async static Task<string> CallWebService(string webWebServiceUrl,
string webServiceNamespace,
string methodVerb,
string methodName,
Dictionary<string, string> parameters) {
const string soapTemplate =
@"<soapenv:Envelope xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope/""
xmlns:{0}=""{2}"">
<soapenv:Header />
<soapenv:Body>
<{0}:{1}>
{3}
</{0}:{1}>
</soapenv:Body>
</soapenv:Envelope>";
var req = (HttpWebRequest)WebRequest.Create(webWebServiceUrl);
req.ContentType = "text/xml"; //"application/soap+xml;";
req.Method = "POST";
string parametersText;
if (parameters != null && parameters.Count > 0)
{
var sb = new StringBuilder();
foreach (var oneParameter in parameters)
sb.AppendFormat(" <{0}>{1}</{0}>\r\n", oneParameter.Key, oneParameter.Value);
parametersText = sb.ToString();
}
else
{
parametersText = "";
}
string soapText = string.Format(soapTemplate,
methodVerb, methodName, webServiceNamespace, parametersText);
Console.WriteLine("SOAP call to: {0}", webWebServiceUrl);
Console.WriteLine(soapText);
using (Stream stm = await req.GetRequestStreamAsync())
{
using (var stmw = new StreamWriter(stm))
{
stmw.Write(soapText);
}
}
var responseHttpStatusCode = HttpStatusCode.Unused;
string responseText = null;
using (var response = (HttpWebResponse)req.GetResponseAsync().Result) {
responseHttpStatusCode = response.StatusCode;
if (responseHttpStatusCode == HttpStatusCode.OK)
{
int contentLength = (int)response.ContentLength;
if (contentLength > 0)
{
int readBytes = 0;
int bytesToRead = contentLength;
byte[] resultBytes = new byte[contentLength];
using (var responseStream = response.GetResponseStream())
{
while (bytesToRead > 0)
{
// Read may return anything from 0 to 10.
int actualBytesRead = responseStream.Read(resultBytes, readBytes, bytesToRead);
// The end of the file is reached.
if (actualBytesRead == 0)
break;
readBytes += actualBytesRead;
bytesToRead -= actualBytesRead;
}
responseText = Encoding.UTF8.GetString(resultBytes);
//responseText = Encoding.ASCII.GetString(resultBytes);
}
}
}
}
return responseText;
//return responseHttpStatusCode;
}
我能够通过使用WSDL.exe来生成您的类(与传统WCF添加服务引用将执行的操作相同),发送请求(如同WCF),添加消息检查器以及在BeforeSendRequest方法中实现此目的捕获生成的Message对象,然后取消WCF Web请求(因为此请求将失败,因为它在dotnet Core中不受支持)。这会生成您发送的必要对象。
那么我刚刚创建了一个dotnet核心HttpClient对象,带有相应的Handler,并发送'WCF generated'请求对象。
如果不够清楚,可能会得到一些代码示例。