【问题标题】:Adding an attachment to SOAP request向 SOAP 请求添加附件
【发布时间】:2012-01-24 09:16:32
【问题描述】:

我对如何在我的 SOAP 请求中添加附件一头雾水。我们必须使用 Java 构建的第三方 Web 服务,这是我遇到过的最复杂的事情。我们使用过的任何其他需要附件的 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>

这是我们可以生成和发送的 XML 部分,但是它是不正确的,因为我们需要一个 MIME 部分,例如:

在 XML 之前:

--MIMEBoundary
Content-Type: application/xop+xml; charset=utf-8; type="text/xml"
Content-Transfer-Encoding: binary
Content-ID: <rootpart>

在 XML 之后

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

--MIMEBoundary--

我已经在互联网上搜索了答案,但一无所获。似乎没有太多关于为此使用 WSE 的文档。我必须强调,WSE 是服务器端的要求,我无法改变技术来解决这个问题。

有没有办法可以添加这些 MIME 部分?

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

我已经添加了一个赏金来尝试解决这个问题。如果有人有任何其他想法,请告诉我。

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

【问题讨论】:

  • WSE 已过时,无论如何都不应使用。
  • 好吧,约翰,想出一个解决方案,而不是四处走动,假装你什么都知道。在这种情况下,对我来说,WSE 是必需的。没有它,我们的请求将被拒绝。我无法告诉第三方供应商他们应该如何编码,我可以尝试,但他们一直是世界上最没有帮助的公司。因此,如果您正在创建自己的软件,则不应使用 WSE,但在这种情况下它是必需的。
  • 很明显,您的公司是否应该继续与要求您使用过时软件的第三方开展业务,而不是某些不使用过时软件的竞争对手,这是一个商业决策。
  • 很明显,但是当它是一家比我们大得多的公司时,我们非常依赖大量收入,对此我们无能为力。如何看待这种工作关系的一个例子,假设我们是一家小型体育用品连锁店,阿迪达斯希望我们这样做,我们不能只是告诉他们我们没有使用 WSE 并从我们的商店中删除该品牌。我们不是运动商店,他们也不是阿迪达斯,但情况非常相似。这不像不使用 WSE 那样简单......
  • 我对此没什么好说的,只是希望有人告诉皇帝他的衣服已经过时了。此外,如果您假装不使用 WSE,那么您无疑将学习如何自定义 WCF 以完成您需要的工作,只需使用受支持的软件。

标签: .net soap attachment mtom wse


【解决方案1】:

我遇到了同样的问题,我找到的最终解决方案是通过 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();            
    }

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

【讨论】:

  • 我不太明白这是怎么工作的。如果您说在内联文件中包含原始数据,那么在我的场景中这是不可能的。它必须包含在我给出的示例中定义的 XOP 部分中。如果我在您的代码中遗漏了这一点,请告知。
  • 该文件应包含您在第一篇文章中描述的 2 个部分:XML 部分和 Ras 数据部分,用 Mime 边界分隔。原始数据部分意味着您的“GIF89a@�”部分应使用以下代码替换为简单字符串: byte[] bt=File.ReadAllBytes(imageFile);string raw=System.Text.Encoding.Unicode.GetString(bt) ;最好直接联系我解释,因为我认为这超出了stackoverflow的范围。
  • HttpWebRequest req = (HttpWebRequest)WebRequest.Create(Settings.Default.GWM_WS_WebReference_GWM); 我无法获得Settings.Default.GWM_WS_WebReference_GWM 我该如何使用它或者有任何替代方法
【解决方案2】:

我认为您可能有几个选择:

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

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

保存方法为SaveToXopPackage,读取方法为LoadFromXopPackage

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

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

【讨论】:

  • 这些只是我在尝试使其工作时使用的参考数量中的一小部分。我可以让它发送一个 MIME 封闭块,但我不知道如何将附件的二进制数据添加到 MIME 部分。
  • 另外,SaveToXopPackage 也可能没有文档,Google 会为它返回 28 个结果,其中大部分是这个确切的页面!
【解决方案3】:

正如您所说您通过 SoapUI 使其工作,我认为您可以向 SoapUI 询问它发送的生成的 XML,以便您知道它的外观,然后修改您的代码以模仿它。

更新:在您发表评论并更详细地阅读其他答案之后:在我看来,该解决方案只是使用 HttpWebRequest 直接发送字节,就像在 ktsiolis 的答案中一样。详细:

  • 创建您的 SOAP XML(您提供的示例),将其编码为 UTF8 中的字节 (1)
  • 使用初始 mimeboundary(“之前 XML”中的部分)创建一个字符串,编码为 UTF8 中的字节 (2)
  • 为第二个 mimeboundary(“XML 之后”的部分)创建字节。 因此,创建包含“--MIMEBOUNDARY”等的字符串,编码为 UTF8 字节,并附加 test.gif 文件的所有字节 (3)
  • 按 (2)、(1) 和 (3) 的顺序附加所有字节并通过网络发送。

这不应该解决问题吗?

【讨论】:

  • 认真的吗?我确切地知道它的外观,我只是不知道如何获取附加到 MIME 部分的二进制数据。
【解决方案4】:

我有 90% 的信心,我正在从事与你们完全相同的项目。那个肥皂请求有点太熟悉了:-)

通过切换到 WCF 并基本上手动编码请求对象(创建匹配肥皂格式的类,然后使用 xmlelement 属性对其进行装饰,使其看起来像他们的肥皂请求),我们已经完成了大部分工作。文件本身在 Attachment 类中声明为 Byte(),并且还使用 xml 元素进行了修饰。

WCF 合同和部分数据模型如下所示。实际的数据模型有一堆额外的类(Application Area、Data Area、Job 等),但这让您对它的结构有足够的了解。重要的部分是 File as Byte()。这是在 Vb.net...

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

接下来,您将获得 WCF 客户端,这与所有 WCF 客户端几乎相同。

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

你终于有了 app.config。这就是神奇之处,因为我们告诉 WCF 使用 Mtom 来发送消息。这将获取 Byte() 并将其剥离到一个单独的 MIME 部分,用 XOP:Include 替换它。请注意,现在我只是通过 localhost 发送它,所以我可以使用 tcpTrace 查看请求。你可以谷歌那个应用程序,但它基本上会捕获请求,所以我们可以看到它的外观。我设置 tcpTrace 监听 84 端口。

<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>

最后,这是对 WCF 客户端发出请求的实际调用。

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)

这是我们通过 tcpTrace 获得的跟踪信息。它具有正确的基本结构,并设法将二进制数据从 xml 中提取出来,并将其放在单独的 MIME 部分中。

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 Header 中缺少一些标签……但我认为我们能够解决这些问题。真正的问题是 Content-ID 不是我们的合作伙伴可以接受的格式 - 他们期望像 和 .net 将它们格式化为 http://tempuri.org/1/634618782531246992。这导致他们的 Web 服务处理程序崩溃,因为它不知道如何读取肥皂消息中的转义内容 ID。

【讨论】:

  • 刚刚注意到您对此的修改。是的,它看起来确实是同一个项目!不幸的是,您的解决方案不适用于我们的案例,因为我们仅限于使用 WSE 而不是 WCF ...依赖于 VS 2005。这很痛苦。但这是我正在寻找的结果,但需要在 WSE 中找出解决方案。 :(但是,对于您的问题,您不能将 Content-ID 设置为您想要的任何内容吗?这在 SoapUI 中有效,当您自己指定 content-ID 并且不依赖默认表示时?我的电子邮件地址,不起作用,如果您想进一步交谈,请在我的个人资料中。
【解决方案5】:

好的,我让它接受来自&lt;gwm:File&gt; 元素中文件的数据。这没有使用 XOP,所以请求现在看起来像:

<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>

当传递给 SoapUI 时,它可以完美运行,但是在代码中它确实会给出响应,但它会抛出一个错误,指出 Response is not well-formed XML. 内部异常为 WSE1608: No XOP parts were located in the stream for the specified content-id: &lt;rootpart*36875c60-630c-4e23-9e74-f9a9c7547fc7@example.jaxws.sun.com&gt;

我将就此提出一个新问题,因为它在技术上是一个不同的问题。

其他问题可以在Soap response, not well formed XML, no XOP parts located, using WSE找到

【讨论】:

    【解决方案6】:

    我参与了完全相同的项目,并且遇到了与此线程中讨论的相同的问题! 我正在使用 vb 2005 和 WSE 3.0 增强功能,即使现在很痛苦,我也能正常工作。直接在 File Property 中写入文件内容时,附件将被合作伙伴接受。 就我而言,这适用于除 PRA 之外的几乎所有交易。在这里,响应是肯定的,并且将传递一个 AttachmentID,但附件不会出现在事务中。

    这是附件部分的示例:

                    <gwm:Attachment>
                      <gwm:File>/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQ...</gwm:File>
                      <gwm:Filename>intro2.jpg</gwm:Filename>
                    </gwm:Attachment>
    

    如果我将 Service 的 RequireMtom 设置为 True,我将收到以下错误:

    “http://www.starstandards.org/webservices/2005/10/transport”innerhalb desselben Startelementtags neu definiert werden 中的 Das Präfix '' kann nicht von ''。

    一方面,它有效,另一方面,我不确定它是否会与 XOP 元素一起发送。

    【讨论】:

    • 我与 Web 服务开发人员讨论过将数据直接放在 &lt;File&gt; 元素中,他们说这不符合他们的规范,他们需要 &lt;xop:Include&gt; 元素。有关我们遇到的问题的进一步描述,请参阅stackoverflow.com/questions/8805095/…。如果您想在此处之外进一步讨论,请查看我的个人资料以获取我的电子邮件地址。
    • 当然...但是我找不到您的电子邮件地址。
    • 如果您在简历下看不到它,它现在位于我个人资料的“关于我”部分。
    • 谢谢...我已经给你发了一封电子邮件。
    猜你喜欢
    • 2016-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-12
    • 1970-01-01
    • 1970-01-01
    • 2021-10-17
    • 1970-01-01
    相关资源
    最近更新 更多