.net 向SOAP请求添加附件

.net 向SOAP请求添加附件,.net,soap,attachment,mtom,wse,.net,Soap,Attachment,Mtom,Wse,对于如何在SOAP请求中添加附件,我没有把握。我们必须使用第三方web服务,它是用java构建的,这是我遇到过的最复杂的事情。我们使用的任何其他需要附件的web服务都有一个方法或属性来添加附件。简单。然而,这一个没有提供这样的方法 我们已经得到了一个版本的SOAP消息,它正是我们想要的XML,但是它是文件中不能添加的MIME部分 例如: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:x

对于如何在SOAP请求中添加附件,我没有把握。我们必须使用第三方web服务,它是用java构建的,这是我遇到过的最复杂的事情。我们使用的任何其他需要附件的web服务都有一个方法或属性来添加附件。简单。然而,这一个没有提供这样的方法

我们已经得到了一个版本的SOAP消息,它正是我们想要的XML,但是它是文件中不能添加的MIME部分

例如:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing">
<soap:Header>
<payloadManifest xmlns="http://<examplePayload>">
<manifest contentID="Content0" namespaceURI="http://<exampleManifest>" element="ProcessRepairOrder" version="2.01" />
</payloadManifest>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsu:Created>2011-12-19T15:25:13Z</wsu:Created>
<wsu:Expires>2011-12-19T15:30:00Z</wsu:Expires>
</wsu:Timestamp>
<wsse:UsernameToken><wsse:Username>username</wsse:Username><wsse:Password>password</wsse:Password></wsse:UsernameToken></wsse:Security></soap:Header><soap:Body><ProcessMessage xmlns="<examplePayload"><payload><content id="Content0">

<s:ProcessRepairOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://example.xsd" xmlns:s="http://<exampleManifest>" xmlns:gwm="http://example">
    <s:ApplicationArea>
        <s:Sender>
            <s:Component>Test</s:Component>
            <s:Task>ProcessAttachment</s:Task>
            <s:CreatorNameCode>Test</s:CreatorNameCode>
            <s:SenderNameCode>XX</s:SenderNameCode>
            <s:DealerNumber>111111</s:DealerNumber>
            <s:DealerCountry>GB</s:DealerCountry>
        </s:Sender>
        <s:CreationDateTime>2010-03-26T13:37:05Z</s:CreationDateTime>
        <s:Destination>
            <s:DestinationNameCode>GM</s:DestinationNameCode>
            <s:DestinationURI/>
            <s:DestinationSoftwareCode>GWM</s:DestinationSoftwareCode>
        </s:Destination>
    </s:ApplicationArea>
    <s:DataArea xsi:type="gwm:DataAreaExtended">
        <s:Process/>
        <s:RepairOrder>
            <s:Header xsi:type="gwm:RepairOrderHeaderExtended">
                <s:DocumentId/>
            </s:Header>
            <s:Job xsi:type="gwm:JobExtended">
                <s:JobNumber/>
                <s:OperationId>Test</s:OperationId>
                <s:OperationName/>
                <s:CodesAndComments/>
                <s:Diagnostics/>
                <s:WarrantyClaim xsi:type="gwm:WarrantyClaimExtended">
                    <s:OEMClaimNumber>00112233445566778899</s:OEMClaimNumber>
                    <gwm:Attachment>
                        <gwm:File><xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:test.gif"/></gwm:File>
                        <gwm:Filename>test.gif</gwm:Filename>
                    </gwm:Attachment>
                </s:WarrantyClaim>
                <s:LaborActualHours>0.0</s:LaborActualHours>
                <s:Technician/>
            </s:Job>
        </s:RepairOrder>
    </s:DataArea>
</s:ProcessRepairOrder>
</content></payload></ProcessMessage></soap:Body></soap:Envelope>

2011-12-19T15:25:13Z
2011-12-19T15:30:00Z
用户名密码
试验
进程附件
试验
XX
111111
国标
2010-03-26T13:37:05Z
转基因的
GWM
试验
00112233445566778899
test.gif
0
这是我们可以生成并发送的XML部分,但这是不正确的,因为我们需要一个MIME部分,如:

在XML之前:

--MIMEBoundary
Content-Type: application/xop+xml; charset=utf-8; type="text/xml"
Content-Transfer-Encoding: binary
Content-ID: <rootpart>
--mimebundary
内容类型:应用程序/xop+xml;字符集=utf-8;type=“text/xml”
内容传输编码:二进制
内容ID:
XML之后

--MIMEBoundary
Content-Type: image/gif; name=test.gif
Content-Transfer-Encoding: binary
Content-ID: <test.gif>
GIF89a@�

--MIMEBoundary--
--mimebundary
内容类型:image/gif;name=test.gif
内容传输编码:二进制
内容ID:
吉福89A@�
--MIME边界--
我在互联网上搜寻答案,结果一无所获。关于使用WSE来实现这一点,似乎没有太多文档。我必须强调,WSE是服务器端的一个需求,我无法改变技术来解决这个问题

有没有办法添加这些MIME部分

编辑:我必须补充一点,我可以通过SoapUI发送一个带有附件的工作XML文档,但似乎无法在代码中找到方法

我增加了一笔赏金,试图找到解决这个问题的办法。如果有人有任何其他想法,请告诉我


再次编辑:我知道我已经有一个星期没能在这里查看回复了,但是尽管有些人给出了一个好主意,我仍然是空白。围绕
XopDocument
及其方法的糟糕文档是一个很大的症结所在,如果有人有任何使用
SaveToXopPackage
的例子,请提供,因为这已经开始变得糟糕

我也面临同样的问题,我找到的最终解决方案是通过HttpWebRequest。 示例代码:

    public string ProcessAttachment(string fileInput)
    {
        HttpWebRequest req = (HttpWebRequest)WebRequest.Create(Settings.Default.GWM_WS_WebReference_GWM);
        req.Headers.Add("SOAPAction", "\"http://www.starstandards.org/webservices/2005/10/transport/operations/ProcessMessage/v1_01/ProcessAttachment\"");
        req.Headers.Add("Accept-Encoding", "gzip,deflate");
        req.ContentType = "multipart/related; type=\"application/xop+xml\"; start=\"<rootpart@soapui.org>\"; start-info=\"text/xml\"; boundary=\"----=_Part_14_1350106.1324254402199\"";
        req.Method = "POST";
        req.UserAgent = "Jakarta Commons-HttpClient/3.1";
        req.Headers.Add("MIME-Version", "1.0");
        System.Net.ServicePointManager.Expect100Continue = false;
        Stream memStream = new System.IO.MemoryStream();
        FileStream fileStream = new FileStream(fileInput, FileMode.Open, FileAccess.Read);
        byte[] buffer = new byte[1024];
        int bytesRead = 0;
        while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
        {
            memStream.Write(buffer, 0, bytesRead);
        }
        fileStream.Close();
        Stream stm = req.GetRequestStream();
        memStream.Position = 0;
        byte[] tempBuffer = new byte[memStream.Length];
        memStream.Read(tempBuffer, 0, tempBuffer.Length);
        memStream.Close();
        stm.Write(tempBuffer, 0, tempBuffer.Length);
        stm.Close();
        HttpWebResponse resp = null;
        resp = (HttpWebResponse)req.GetResponse();
        stm = resp.GetResponseStream();
        StreamReader r = new StreamReader(stm);
        return r.ReadToEnd();            
    }
公共字符串处理附件(字符串文件输入)
{
HttpWebRequest req=(HttpWebRequest)WebRequest.Create(Settings.Default.GWM_WS_WebReference_GWM);
添加(“SOAPAction”、“\”http://www.starstandards.org/webservices/2005/10/transport/operations/ProcessMessage/v1_01/ProcessAttachment\"");
添加(“接受编码”、“gzip、deflate”);
req.ContentType=“多部分/相关;类型=\”应用程序/xop+xml\“开始=\”“开始信息=\”文本/xml\“边界=\”----=\u部分\u 14\u 1350106.1324254402199\”;
请求方法=“POST”;
req.UserAgent=“Jakarta Commons HttpClient/3.1”;
添加(“MIME版本”、“1.0”);
System.Net.ServicePointManager.Expect100Continue=false;
Stream memStream=new System.IO.MemoryStream();
FileStream FileStream=newfilestream(fileInput,FileMode.Open,FileAccess.Read);
字节[]缓冲区=新字节[1024];
int字节读取=0;
而((bytesRead=fileStream.Read(buffer,0,buffer.Length))!=0)
{
memStream.Write(缓冲区,0,字节读取);
}
fileStream.Close();
Stream stm=req.GetRequestStream();
memStream.Position=0;
byte[]tempBuffer=新字节[memStream.Length];
memStream.Read(tempBuffer,0,tempBuffer.Length);
memStream.Close();
stm.Write(tempBuffer,0,tempBuffer.Length);
stm.Close();
HttpWebResponse resp=null;
resp=(HttpWebResponse)req.GetResponse();
stm=resp.GetResponseStream();
StreamReader r=新StreamReader(stm);
返回r.ReadToEnd();
}

参数fileInput是包含SOAP请求的文件的绝对路径,该SOAP请求还包含要附加在末尾的文件的原始二进制数据,以MIME边界分隔

我认为您可能有两个选项:

1) 使用。这似乎会自动将传出消息包装在MIME块中

2) Microsoft实际上通过XopDocument类提供了对使用mime生成和读取XOP的支持,这是SoapEnvelope继承的

保存方法为,读取方法为

但是,我认为这种方法可能需要您自己通过HttpWebRequest发送消息。有一个如何实现这一点的示例。缺点是,这需要大量额外的代码和配置才能正常工作


理想的解决方案是截取执行信封传输的代码,但我一直无法在管道中找到正确的位置。

正如您所说,它是通过SoapUI工作的,我认为您可以向SoapUI询问它发送的生成XML,以便您知道它应该是什么样子,然后修改您的代码以模仿它

更新:在您的评论和阅读其他更详细的答案之后:我认为解决方案看起来只是直接发送字节,使用HttpWebRequest,就像ktsiolis的答案一样。详细内容:

  • 创建SOAP XML(您给出的示例),将其编码为UTF8(1)中的字节
  • 创建一个
    Public Class WarrantyClaim
        <XmlElement(Order:=0)> Public OEMClaimNumber As String = ""
        <XmlElement(Order:=1, namespace:="http://www.gm.com/2006/GWM")> Public Attachment As New Attachment
    End Class
    
    Public Class Attachment
        <XmlElement(Order:=0)> Public File As Byte()
        <XmlElement(Order:=1)> Public Filename As String
    End Class
    
    <ServiceContract(XmlSerializerFormat()> _
    Public Interface IService
        <OperationContract(action:="http://www.starstandards.org/webservices/2005/10/transport/operations/ProcessMessage/v1_01/ProcessAttachment")> _
        Sub ProcessMessage(ByVal payload As WarrantyClaim)
    End Interface
    
    Public Class GmgwClient
        Inherits System.ServiceModel.ClientBase(Of IService)
        Implements IService
    
        Public Sub New()
            MyBase.New()
        End Sub
        Public Sub New(ByVal configName As String)
            MyBase.New(configName)
        End Sub
        Public Sub New(ByVal binding As System.ServiceModel.Channels.Binding, ByVal remoteAddress As System.ServiceModel.EndpointAddress)
            MyBase.New(binding, remoteAddress)
        End Sub
    
        Public Sub ProcessMessage(ByVal payload As Payload) Implements IService.ProcessMessage
            MyBase.Channel.ProcessMessage(payload)
        End Sub
    End Class
    
    <system.serviceModel>
      <bindings>
        <wsHttpBinding>
          <binding name="WsHttpMtomBinding" messageEncoding="Mtom">
            <security mode="None">
              <transport clientCredentialType="Basic" proxyCredentialType="None" realm="" />
            </security>
            <reliableSession enabled="false" />
          </binding>
        </wsHttpBinding>
      </bindings>
      <client>
        <endpoint address="http://localhost:84/ProcessMessage" binding="wsHttpBinding" bindingConfiguration="WsHttpMtomBinding" contract="MyAppNameSpace.IService" name="preprod"/>
      </client>
    </system.serviceModel>
    
    Dim x As New WarrantyClaim
    x.OEmClaimNumber = "12345"
    x.Attachment = New Attachment
    x.Attachment.Filename = "sample.gif"
    x.Attachment.File = IO.File.ReadAllBytes("C:\sample.gif")
    
    Dim y As New GmgwClient("preprod")
    y.ProcessMessage(x)
    
    POST /ProcessMessage HTTP/1.1
    MIME-Version: 1.0
    Content-Type: multipart/related; type="application/xop+xml";start="<http://tempuri.org/0>";boundary="uuid:501aa27d-9dd1-4f8a-b56d-3fbf327e7be6+id=1";start-info="application/soap+xml"
    VsDebuggerCausalityData: uIDPoysDMCv023ZIjK0Cpp504ooAAAAA//jfaCaohkab2Zx/EU7gpLZDcUldWtlGr1j4ZnrfKl4ACQAA
    Host: localhost:84
    Content-Length: 55125
    Expect: 100-continue
    Accept-Encoding: gzip, deflate
    Connection: Keep-Alive
    
    
    --uuid:501aa27d-9dd1-4f8a-b56d-3fbf327e7be6+id=1
    Content-ID: <http://tempuri.org/0>
    Content-Transfer-Encoding: 8bit
    Content-Type: application/xop+xml;charset=utf-8;type="application/soap+xml"
    
    <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
      <s:Header>
        <a:Action s:mustUnderstand="1">http://www.starstandards.org/webservices/2005/10/transport/operations/ProcessMessage/v1_01/ProcessAttachment</a:Action>
        <a:MessageID>urn:uuid:a85374e6-c8ca-4328-ad32-6e8b88a5ca59</a:MessageID>
        <a:ReplyTo>
          <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
        </a:ReplyTo>
        <a:To s:mustUnderstand="1">http://localhost:84/ProcessMessage</a:To>
      </s:Header>
      <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <ProcessMessage xmlns="http://www.starstandards.org/webservices/2005/10/transport">
          <payload xsi:type="gwm:WarrantyClaimExtended">
            <OEMClaimNumber>12345</OEMClaimNumber>
            <Attachment xmlns="http://www.gm.com/2006/GWM">
              <File>
                <xop:Include href="cid:http%3A%2F%2Ftempuri.org%2F1%2F634618782531246992" xmlns:xop="http://www.w3.org/2004/08/xop/include"/>
              </File>
              <Filename>sample.gif</Filename>
            </Attachment>
          </payload>
        </ProcessMessage>
      </s:Body>
    </s:Envelope>
    --uuid:501aa27d-9dd1-4f8a-b56d-3fbf327e7be6+id=1
    Content-ID: <http://tempuri.org/1/634618782531246992>
    Content-Transfer-Encoding: binary
    Content-Type: application/octet-stream
    
    GIF89a<BinaryStuff>
    
    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing">  <soap:Header>  <payloadManifest xmlns="http://<examplePayload>">  <manifest contentID="Content0" namespaceURI="http://<exampleManifest>" element="ProcessRepairOrder" version="2.01" />  </payloadManifest>  <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> <wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <wsu:Created>2011-12-19T15:25:13Z</wsu:Created>  <wsu:Expires>2011-12-19T15:30:00Z</wsu:Expires>  </wsu:Timestamp>  <wsse:UsernameToken><wsse:Username>username</wsse:Username><wsse:Password>password</wsse:Password></wsse:UsernameToken></wsse:Security></soap:Header><soap:Body><ProcessMessage xmlns="<examplePayload"><payload><content id="Content0">    <s:ProcessRepairOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://example.xsd" xmlns:s="http://<exampleManifest>" xmlns:gwm="http://example"> 
        <s:ApplicationArea> 
            <s:Sender> 
                <s:Component>Test</s:Component> 
                <s:Task>ProcessAttachment</s:Task> 
                <s:CreatorNameCode>Test</s:CreatorNameCode> 
                <s:SenderNameCode>XX</s:SenderNameCode> 
                <s:DealerNumber>111111</s:DealerNumber> 
                <s:DealerCountry>GB</s:DealerCountry> 
            </s:Sender> 
            <s:CreationDateTime>2010-03-26T13:37:05Z</s:CreationDateTime> 
            <s:Destination> 
                <s:DestinationNameCode>GM</s:DestinationNameCode> 
                <s:DestinationURI/> 
                <s:DestinationSoftwareCode>GWM</s:DestinationSoftwareCode> 
            </s:Destination> 
        </s:ApplicationArea> 
        <s:DataArea xsi:type="gwm:DataAreaExtended"> 
            <s:Process/> 
            <s:RepairOrder> 
                <s:Header xsi:type="gwm:RepairOrderHeaderExtended"> 
                    <s:DocumentId/> 
                </s:Header> 
                <s:Job xsi:type="gwm:JobExtended"> 
                    <s:JobNumber/> 
                    <s:OperationId>Test</s:OperationId> 
                    <s:OperationName/> 
                    <s:CodesAndComments/> 
                    <s:Diagnostics/> 
                    <s:WarrantyClaim xsi:type="gwm:WarrantyClaimExtended"> 
                        <s:OEMClaimNumber>00112233445566778899</s:OEMClaimNumber> 
                        <gwm:Attachment> 
                            <gwm:File>GIF89a@�</gwm:File> 
                            <gwm:Filename>test.gif</gwm:Filename> 
                        </gwm:Attachment> 
                    </s:WarrantyClaim> 
                    <s:LaborActualHours>0.0</s:LaborActualHours> 
                    <s:Technician/> 
                </s:Job> 
            </s:RepairOrder> 
        </s:DataArea>  </s:ProcessRepairOrder>  </content></payload></ProcessMessage></soap:Body></soap:Envelope>
    
                    <gwm:Attachment>
                      <gwm:File>/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQ...</gwm:File>
                      <gwm:Filename>intro2.jpg</gwm:Filename>
                    </gwm:Attachment>