我正在为外部客户端设置Web服务以连接到我的客户端应用程序并更新一些信息。我去了ASMX路线(其余的应用程序在WCF上运行),因为我知道外部客户端可能很难处理,我试图尽可能简单地保持一切。他们也不是一个让事情变得更糟的.Net商店。获得服务设置后,我为他们提供了ASMX URL,以了解如何格式化SOAP标头/消息内容。他们回来告诉我他们的工具无法以.Net要求的格式发送它们,我可以用不同的方式接受消息,或者我们必须使用FTP。
基于此,我一直在研究如何拦截他们的消息,按照我的服务需要的方式重新格式化(这意味着添加两行),然后让它处理。这条路径引导我进入SOAP扩展,我一直试图与之合作,但似乎无法弄清楚。当我有我的示例应用程序从生成的代码调用Web服务添加Web引用提供一切正常,直到我添加我的扩展。它目前所做的只是覆盖ChainStream设置一个内部流,它等于传入的内部流并返回一个新流,如下所示:
private Stream newStream = null;
private Stream oldStream = null;
public override Stream ChainStream(Stream stream)
{
this.oldStream = stream;
this.newStream = new MemoryStream();
return newStream;
}
我还重写ProcessMessage,并在其中获取oldStream的内容并将newStream设置为等于该值,然后使用XmlWriter写入不同的流。我接受新的流并使用StreamReader将其读入一个字符串,最终目标是在这里操作它并设置newStream(由ChainStream使用)等于此内容。这是一块:
public override void ProcessMessage(SoapMessage message)
{
switch (message.Stage)
{
case SoapMessageStage.BeforeDeserialize:
this.Process();
break;
default: break;
}
}
private void Process()
{
this.newStream.Position = 0L;
XmlTextReader reader = new XmlTextReader(this.oldStream);
MemoryStream outStream = new MemoryStream();
using (XmlWriter writer = XmlWriter.Create(outStream))
{
do { writer.WriteNode(reader, true); } while (reader.Read());
writer.Flush();
}
outStream.Seek(0, SeekOrigin.Begin);
StreamReader streamReader = new StreamReader(outStream);
string message = streamReader.ReadToEnd();
newStream = outStream;
newStream.Seek(0, SeekOrigin.Begin);
streamReader.Close();
}
通过运行这个,我觉得它很好,我的测试应用程序从服务中获得400 Bad Request。如果我要么不使用扩展,要么我在ProcessMessage中没有做任何事情似乎都很好。有什么建议吗?
作为旁注,一旦我使用来自WSDL的生成代码,我将转移到WebRequest以尝试将消息发送到服务。目前,这是一个415不支持的媒体类型响应炸弹。我试图将这篇文章保留为一个问题,但如果有人使用WebRequest连接到ASMX服务有任何提示,我将不胜感激!
答案 0 :(得分:1)
我意识到这不是您正在寻找的答案,但为什么不使用REST而不是SOAP?由于该服务的主要(唯一?)消费者不会遵守,因此尝试“修复”他们的呼叫只是额外的一层复杂性。
相反,只需使用接受查询字符串或xml请求主体上的数据的aspx页面,处理它,然后将xml(或其他格式)响应流回给它们。
你失去了自动生成类型信息等的Visual Studio SOAP“magic”,但由于他们没有使用(或者不允许使用)带有SOAP库的语言,这对任何人都没有帮助