了解带有附件 (SwA) 的 WCF Multipart Soap 服务/端点

Posted

技术标签:

【中文标题】了解带有附件 (SwA) 的 WCF Multipart Soap 服务/端点【英文标题】:Understanding WCF Multipart Soap service/endpoint with Attachment (SwA) 【发布时间】:2020-09-12 00:44:21 【问题描述】:

我正在尝试了解如何创建/反向设计一个 Multipart WCF Soap 端点,该端点将附件作为输入参数,由“MIME-delimiter”分隔。

我举了一个例子,说明谁会向这种端点发出请求,但我不明白如何创建服务来接收请求。

所以我得到的示例是这样的(仅供参考,出于安全原因,我已删除信息):

--MIME11111.11111
<SOAP-ENV:Envelope xmlns:SOAP-ENV="" xmlns:eb="" xmlns:xsi="" xsi:schemaLocation="">
  <SOAP-ENV:Header>
    <eb:MessageHeader SOAP-ENV:mustUnderstand="1" eb:version="2.0">
      <eb:From>
        <eb:PartyId eb:type="TYPE1">NUMBER</eb:PartyId>
      </eb:From>
      <eb:To>
        <eb:PartyId eb:type="TYPE2">NUMBER</eb:PartyId>
      </eb:To>
      <eb:CPAId>ID</eb:CPAId>
      <eb:Service eb:type="TYPE3">TEXT</eb:Service>
      <eb:Action>TEXT</eb:Action>
      <eb:MessageData>
        <eb:MessageId>ID</eb:MessageId>
        <eb:Timestamp>DATE</eb:Timestamp>
      </eb:MessageData>
    </eb:MessageHeader>
  </SOAP-ENV:Header>
  <SOAP-ENV:Body>
    <eb:Manifest eb:version="2.0">
      <eb:Reference xlink:href="cid:payload-1" xlink:role="aop:ROOT"/>
    </eb:Manifest>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

--MIME11111.11111
Content-ID: payload-1

<?xml version="1.0" encoding="UTF-8"?>
<aop:ROOT xsi:schemaLocation="" xmlns:aop="" xmlns:xsi="">
    <aop:ELEMENT>
        <aop:SUBELEMENT11>TEXT</aop:SUBELEMENT11>
        <aop:SUBELEMENT12>
            <aop:SUBELEMENT21>NUMBER</aop:SUBELEMENT21>
            <aop:SUBELEMENT22>NUMBER</aop:SUBELEMENT22>
        </aop:SUBELEMENT12>
    </aop:ELEMENT>
</aop:ROOT>
--MIME11111.11111--

到目前为止我所做的是:

    在 Visual Studio 中创建了一个 WCF 项目。

    这样创建我的界面:

    [ServiceContract]
    public interface IService1
    
    
       [OperationContract]
       [WebInvoke(Method = "Post", BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "/PostBusinessData")]
       PostBusinessDataResponseContract PostBusinessData(Manifest data);
    
    
    
    [MessageContract]
    public class Manifest
    
       [MessageHeader]
       public Headers MessageHeader  get; set; 
    
       [MessageBodyMember]
       public Stream Reference  get; set; 
    
    
    [MessageContract]
    public class PostBusinessDataResponseContract
    
       [MessageBodyMember]
       public string PostBusinessDataResponse  get; set; 
    
    

    像这样创建我的控制器/服务:

    public class Service1 : IService1
    
        public PostBusinessDataResponseContract PostBusinessData(Manifest data)
        
            return new PostBusinessDataResponseContract()  PostBusinessDataResponse = "It Works";
        
    
    

    我的 Header 类是通过在上例中的“header”元素之间“特殊粘贴”XML 结构而创建的。

我已经为soap-envelope标头设置了类Model,除了元素上的一些属性在生成的请求结构中显示为子元素。

但主要是我不太明白如何为附件中的 in 参数构建代码。在我看来,多部分示例中的附件是作为流出现的,但是作为什么流?一个文件,一个xml字符串/文本? SOAP 信封中的引用包含的唯一内容是所谓的“Content-ID”。没有文件名,没有别的。

如何在我的 backed 中设置我的端点以便能够使用上面示例中显示的请求类型真的是我的问题。

【问题讨论】:

【参考方案1】:

根据你的描述,我做了一个demo。创建 WCF 服务后,我们可以通过添加服务引用来生成一个代理类来调用该服务。

右键单击引用并选择添加服务引用。

在地址栏输入服务的地址,点击确定生成代理类和配置文件,供你调用服务。

      ServiceReference1.Service1Client service1Client = new Service1Client();
        string str = "Testing";        
        byte[] array = Encoding.ASCII.GetBytes(str);
        MemoryStream stream = new MemoryStream(array);
        Console.WriteLine(service1Client.PostBusinessData(stream));
        Console.ReadLine();

客户端可以通过生成的代理类支持服务器的请求类型。

这是结果。

更新

WCF 支持 MTOM,这是 W3C 标准取代 SwA。这是指向 MTOM 相关信息的链接:

https://docs.microsoft.com/en-us/dotnet/framework/wcf/samples/mtom-encoding

有关 MTOM 和 SWA 的更多信息,请参考以下链接:

https://docs.microsoft.com/en-us/previous-versions/dotnet/articles/ms996462(v=msdn.10)?redirectedfrom=MSDN

在WCF中,如果你想接收你给出的XML消息,我认为你可以使用消息检查器来截取XML消息并解析它。

    public class ServerMessageLogger : IDispatchMessageInspector

    public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
    

        string xml = ""+request;
       // Parse the received XML here
        return null;
    

    public void BeforeSendReply(ref Message reply, object correlationState)
    

        string xml = ""+reply;
        //Encapsulate the XML to send
    

有关消息检查器的更多信息,请参考以下链接:

https://docs.microsoft.com/en-us/dotnet/framework/wcf/samples/message-inspectors?redirectedfrom=MSDN

【讨论】:

首先非常感谢您抽出宝贵的时间来完成这个。非常感激!其次,我是否正确理解您在“参考”元素中发送字符串?在您最后一张图片的“接收”部分中,我看不到引用第二个多部分部分中的附件的引用,该部分由“mime”分隔符分隔。如果您查看我收到的请求示例(代码 sn-p 的第一个示例),您会看到“参考”部分指的是某种尾随附件。

以上是关于了解带有附件 (SwA) 的 WCF Multipart Soap 服务/端点的主要内容,如果未能解决你的问题,请参考以下文章

没有 MEX 端点的带有 BasicHttpBinding 的 WCF 服务可以被绝对陌生的人利用吗?

Python:试图通过电子邮件发送附件〜字符串错误?

为 http 和 https 端点配置带有路由 (global.asax) 的 WCF 4

在 Ubuntu 服务器上使用带有附件的 php 脚本发送邮件 [重复]

exchange 邮箱附件被拦截问题

如何防止 Apache PDFBox 中的通用签名伪造 (USF)、增量保存攻击 (ISA)、签名包装 (SWA)