IRS-A2A BulkRequestTransmitter消息未正确格式化和/或无法解释

Rus*_*uss 5 c# xml soap-client irs

尝试通过BulkRequestTransmitter Web服务提交时,我收到以下错误.对于此消息,组合指南不太有用,当我将SOAP XML与Composition Guide中的SOAP进行比较时,它们似乎是一对一的.我希望另一组眼睛能够看到问题所在.

消息格式不正确和/或无法解释.请查看位于https://www.irs.gov/for-Tax-Pros/Software-Developers/Information-Returns/Affordable-Care-Act-Information的"AIR提交组合和参考指南"第3节中概述的XML标准.-Return-AIR-Program,更正任何问题,然后重试.

我试过的:

  • 尝试在SOAP Envelope中提交(和不提供)空格.
  • 尝试使用XML格式的表单数据XML进行提交.
  • 尝试以base64string格式提交表格数据(如此提交内容).
  • ds为Signature元素添加了前缀.使用此SO帖子以便为Signature元素添加前缀.
  • 添加了"漂亮打印"格式的表格数据,并根据更新的作文指南(v4.2)添加.
  • 复制" 构图指南" 第10.3节中列出MIMEBulkTransmitterService请求的格式.
  • 创建了两个解决方案:1.)手动创建SOAP请求所需的XML并通过HttpWebRequest对象发送; 2.)通过WSDL导入到项目的发送提交请求Service Reference,使用自定义编码器GZip and Mtom Encoding并手动创建SOAP状态请求所需的XML(通过发送HttpWebRequest).

更新#1
根据一些新增内容更新了请求.

  • ds为Signature元素添加了前缀.
  • 添加了"漂亮打印"格式的表格数据,并根据更新的作文指南(v4.2:第5.4.2节)添加.

更新#2
我开始SOAP在Visual Studio的新实例中手动创建.xml文件,根据需要导入模式引用.我在任何类型的应用程序创建之外这样做.

通过这样做,我能够SOAP通过我的应用程序找到一些额外的错误(感谢intellisense!).我发现的错误是在Manifest XML中,因为它们不符合IRS模式.

我将在接下来的24小时内查看这些内容并进行相应更新.

  • urn:MailingAddressGrp应具有的任何一个孩子urn:USAddressGrpurn:ForeignAddressGrp.那个孩子应该包含适当的地址元素.我的代码目前缺少直接的孩子urn:MailingAddressGrp.
  • urn1:DocumentSystemFileNmof 的值Form1094C_Request_[TCC]_yyyyMMddThhmmssfffZ.xml不正确.我还不完全确定它应该是什么.
  • urn1:BulkExchangeFile元素存在与xop:Include我所拥有的元素相关的问题.架构需要base64Binary类型.

更新#2.5

  • 更新了我的XML生成过程以包含该USAddressGrp元素.
  • 发现我在毫秒内有一个额外的字符(四个而不是三个).一旦我更正了这一点,同时从文件名的开头删除字符串"Form",该值urn1:DocumentSystemFileNm就能够成功验证模式.

更新#3

  • 根据我所做的更新更新了完整请求.此时,我无法推断出我的请求有什么问题.如果有人看到任何明显的东西,请帮忙!

更新#4

  • 根据所做的其他更新更新了完整请求.ds根据其他SO用户的反馈从签名中删除了前缀.该用户已经使这些请求工作,而不必ds在事后将该前缀附加到签名并重新计算签名.

    SO用户还确认他的请求正在使用 <inc:Include>被设置为元素的子元素的 <BulkExchangeFile>元素.

  • MIME根据"合成指南"第10.3节中的示例确认标题是正确的.

更新#5

  • 我目前有两个解决方案:一个是手动创建SOAP请求和发送所需的XML HttpWebRequest; 并使用WSDL Service Reference下面列出的自定义编码器使用提交请求,并手动创建状态的SOAP请求所需的XML.

    在此更新时,解决方案1在提交提交请求时给出了上述错误,并在进行状态请求时给出了以下错误.但是,在使用解决方案2时,两个请求(提交和状态)都会给出以下错误.

    我正在研究可能的证书问题,看看他们是否在这些解决方案中取得任何进展.

更新#6

我遇到了一些问题导致我被推迟.我将免除你的细节,但是,缺点是我们没有在IRS系统注册的安全证书,我们也没有正确安装证书,以便我可以通过X509Store.最后这些事情已经完成,我能够测试从服务器向IRS提交数据(与我没有正确证书的本地机器相比).不幸的是,我仍然收到下面详述的WS-Security错误.我已使用我目前发送的内容更新了完整请求.

消息发生错误:消息中的WS安全标头无效.请检查在AIR提交组成和参考指南位于第5段所述的传输指令https://www.irs.gov/for-Tax-Pros/Software-Developers/Information-Returns/Affordable-Care-Act-Information -Return-AIR-Program,更正任何问题,然后重试.


MIME标头中的所有换行符都是原样,我相信换行符是预期的. FormData附件以Pretty Print的形式发送,而SOAP Envelope则不是; 此帖子中的SOAP信封的格式是为了便于阅读.

更新#7:

感谢用户:jstill和fatherOfWine以及他们在下面发布的内容,以及Bon对此项目的早期帮助.在提交提交作品时,我突破了一面墙.它现在正在运作.状态请求也正常.但是,我需要弄清楚如何处理它以便从中提取状态和附件(错误数据文件).

完整要求:

Content-Encoding: gzip
Accept-Encoding: gzip, deflate
Content-Type: multipart/related; type="application/xop+xml"; start="<rootpart>"; start-info="text/xml"; boundary="MIME_boundary"
SOAPAction: BulkRequestTransmitter
MIME-Version: 1.0
Host: la.www4.irs.gov

--MIME_Boundary
Content-Type: application/xop+xml; charset=UTF-8; type="text/xml"
Content-Transfer-Encoding: 8bit
Content-Id: <root_part>

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Header>
        <Security xmlns:h="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
            <Signature Id="SIG-E77c57b78ebc54e989bfc9e43604a04a4" xmlns="http://www.w3.org/2000/09/xmldsig#">
                <SignedInfo>
                    <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#WithComments" />
                    <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
                    <Reference URI="#TS-Eb4799bee41bb4df0a72f52832d283ef7">
                        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
                        <DigestValue>[TimestampDigestValue]</DigestValue>
                    </Reference>
                    <Reference URI="#id-E5f1ed32aab8f4578adeee5debd851a62">
                        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
                        <DigestValue>[ACABusinessHeaderDigestValue]</DigestValue>
                    </Reference>
                    <Reference URI="#id-E4a71164001994d7f865fc7ddb8055350">
                        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
                        <DigestValue>[ManifestDigestValue]</DigestValue>
                    </Reference>
                </SignedInfo>
                <SignatureValue>[SignatureValue]</SignatureValue>
                <KeyInfo Id="KI-E2309cb142e1a4076a2e71373e6e6b75f">
                    <SecurityTokenReference d6p1:Id="STR-E2751169ee468470290fe5e8bfb34589e" xmlns:d6p1="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
                        <KeyIdentifier EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3">[KeyIdentifier]</KeyIdentifier>
                    </SecurityTokenReference>
                </KeyInfo>
            </Signature>
            <a:Timestamp a:Id="TS-Eb4799bee41bb4df0a72f52832d283ef7" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:a="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
                <a:Created>2016-05-18T09:51:05.856Z</a:Created>
                <a:Expires>2016-05-18T10:01:05.856Z</a:Expires>
            </a:Timestamp>
        </Security>
        <ACATransmitterManifestReqDtl a:Id="id-E4a71164001994d7f865fc7ddb8055350" xmlns:h="urn:us:gov:treasury:irs:ext:aca:air:7.0" xmlns:a="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns="urn:us:gov:treasury:irs:ext:aca:air:7.0">
            <PaymentYr>2015</PaymentYr>
            <PriorYearDataInd>0</PriorYearDataInd>
            <EIN xmlns="urn:us:gov:treasury:irs:common">000000301</EIN>
            <TransmissionTypeCd>O</TransmissionTypeCd>
            <TestFileCd>T</TestFileCd>
            <OriginalReceiptId />
            <TransmitterNameGrp>
                <BusinessNameLine1Txt />
            </TransmitterNameGrp>
            <CompanyInformationGrp>
                <CompanyNm>Selitestthree</CompanyNm>
                <MailingAddressGrp>
                    <USAddressGrp>
                        <AddressLine1Txt>6689 Willow Court</AddressLine1Txt>
                        <CityNm xmlns="urn:us:gov:treasury:irs:common">Beverly Hills</CityNm>
                        <USStateCd>CA</USStateCd>
                        <USZIPCd xmlns="urn:us:gov:treasury:irs:common">90211</USZIPCd>
                    </USAddressGrp>
                </MailingAddressGrp>
                <ContactNameGrp>
                    <PersonFirstNm>Rose</PersonFirstNm>
                    <PersonLastNm>Lincoln</PersonLastNm>
                </ContactNameGrp>
                <ContactPhoneNum>5559876543</ContactPhoneNum>
            </CompanyInformationGrp>
            <VendorInformationGrp>
                <VendorCd>I</VendorCd>
                <ContactNameGrp>
                    <PersonFirstNm>ContactFirstName</PersonFirstNm>
                    <PersonLastNm>ContactLastName</PersonLastNm>
                </ContactNameGrp>
                <ContactPhoneNum>ContactPhoneNumber</ContactPhoneNum>
            </VendorInformationGrp>
            <TotalPayeeRecordCnt>3</TotalPayeeRecordCnt>
            <TotalPayerRecordCnt>1</TotalPayerRecordCnt>
            <SoftwareId>PPACA</SoftwareId>
            <FormTypeCd>1094/1095C</FormTypeCd>
            <BinaryFormatCd xmlns="urn:us:gov:treasury:irs:common">application/xml</BinaryFormatCd>
            <ChecksumAugmentationNum xmlns="urn:us:gov:treasury:irs:common">6b2512ce28f603f76261923d297738e5</ChecksumAugmentationNum>
            <AttachmentByteSizeNum xmlns="urn:us:gov:treasury:irs:common">14076</AttachmentByteSizeNum>
            <DocumentSystemFileNm>1094C_Request_[TCC]_20160518T215105716Z.xml</DocumentSystemFileNm>
        </ACATransmitterManifestReqDtl>
        <ACABusinessHeader a:Id="id-E5f1ed32aab8f4578adeee5debd851a62" xmlns:h="urn:us:gov:treasury:irs:msg:acabusinessheader" xmlns:a="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns="urn:us:gov:treasury:irs:msg:acabusinessheader">
            <UniqueTransmissionId xmlns="urn:us:gov:treasury:irs:ext:aca:air:7.0">51958882-c653-4eab-8dfb-287ecc555aaa:SYS12:[TCC]::T</UniqueTransmissionId>
            <Timestamp xmlns="urn:us:gov:treasury:irs:common">2016-05-18T14:51:05.8568594-07:00</Timestamp>
        </ACABusinessHeader>
    </s:Header>
    <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <ACABulkRequestTransmitter xmlns="urn:us:gov:treasury:irs:msg:irsacabulkrequesttransmitter" version="1.0">
            <BulkExchangeFile xmlns="urn:us:gov:treasury:irs:common">
                <inc:Include href="cid:1094C_Request_BB0S4_20160518T215105716Z.xml" xmlns:inc="http://www.w3.org/2004/08/xop/include" />
            </BulkExchangeFile>
        </ACABulkRequestTransmitter>
    </s:Body>
</s:Envelope>

--MIME_Boundary
Content-Type: text/xml; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Id: <1094C_Request_[TCC]_20160518T215105716Z.xml>
Content-Disposition: attachment; name="1094C_Request_[TCC]_20160518T215105716Z.xml"

[PrettyPrintFormDataXml]
--MIME_boundary--
Run Code Online (Sandbox Code Playgroud)

fat*_*ine 4

不知道它是否能解决您的问题,但我还是尝试一下。有时帮助来自非常意想不到的来源:)

\n\n
    \n
  1. 首先,时间戳字段的格式错误:\nbusinessheader 中的一个根本不应包含毫秒。我确实知道这一点。
  2. \n
  3. 在安全标头时间戳中,只允许使用 3 位数字来表示\n毫秒。
  4. \n
  5. 从 ACATransmitterManifestReqDtl 元素中删除“OriginalReceiptId”等空元素:他们不喜欢这些元素。
  6. \n
  7. 我希望您为他们提供正确的软件 ID,因为有效负载中的软件 ID 为空,但我相信他们会很乐意拥有它,恕我直言。:)
  8. \n
  9. 我认为您在响应中收到的消息也与签名元素有关。我认为他们希望 Signature 元素有一些前缀(我猜最好是“ds”)。但在这里我并不能100%确定。

    \n\n

    你看,我正在和你进行同样的战斗。我的消息安全时间戳有前缀“u”,他们并没有抱怨它。尽管他们从来不喜欢binarysecuritytoken。:)我正在努力生成符合国税局喜欢的签名。WCF 非常保密,不允许在肥皂信封上轻松更改前缀,也不允许为签名选择 CanonicalizationMethod 算法。

  10. \n
\n\n

更新:能够成功向服务发送请求。马上告诉你:前缀不重要。重要的是:Form1095BUpstreamDetail 中必须存在 CorrectedInd 标记,并且属性 recordType="String" lineNum="0" 也必须存在。

\n\n

UPDATE2:\n我更改的另一件事是我将 ACABusinessHeader 放在 ManifestDtl 之前。\n以下是我的设置:我使用 WCF 作为载体并使用 SignedXml 来生成签名。另外,我正在使用自定义 gZip 编码器(出于明显的原因0和自定义 MtomEncoder 来读取服务的响应(是的,是的,它是 MTOMed:))你能相信那些神奇宝贝吗?!?!?)这还不是全部:他们将响应作为多部分文档发送,只有 1 部分!:)) 我必须调整我的编码器来处理这个问题。瞧\xc3\xa0,服务开始运行。希望它可能有所帮助。

\n\n

UPDATE3 \n首先确保附件文件中的数据对应于您用作豚鼠的测试场景。我,可能,听起来像一张破唱片,但这真的很重要。\n现在我将剪掉这些东西并展示我所拥有的。这有点粗糙,但它确实有效。:)

\n\n

1.这是配置文件部分:
\n1.1.确保system.serviceModel元素包含以下部分:

\n\n
<extensions>\n  <bindingElementExtensions>\n    <add name="gzipMessageEncoding" type="<namespaceWhereEncoderLives>.GZipMessageEncodingElement, GZipEncoder, Version=4.0.0.0, Culture=neutral, PublicKeyToken=null" />\n  </bindingElementExtensions>\n</extensions>  \n
Run Code Online (Sandbox Code Playgroud)\n\n

1.2. 确保绑定元素包含以下内容:

\n\n
  <customBinding>\n    <binding name="BulkRequestTransmitterBinding">\n      <gzipMessageEncoding innerMessageEncoding="textMessageEncoding" />\n      <httpsTransport />\n    </binding>\n  </customBinding>\n
Run Code Online (Sandbox Code Playgroud)\n\n

1.3. 将客户端元素下的 BulkRequestTransmitterPort 端点的绑定更改为“customBinding”(并将绑定名称也更改为自定义绑定的名称),并确保它包含以下部分:

\n\n
    <identity>\n      <dns value="domain from cert" />\n    </identity>\n
Run Code Online (Sandbox Code Playgroud)\n\n

客户端元素还应包含以下部分:

\n\n
  <metadata>\n    <policyImporters>\n      <extension type="NamespaceToToTheLocationOf.GZipMessageEncodingBindingElementImporter, GZipMessageEncoder, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />\n    </policyImporters>\n  </metadata>\n
Run Code Online (Sandbox Code Playgroud)\n\n
    \n
  1. 您可以从以下链接获取 GZip 编码器:\n https://msdn.microsoft.com/en-us/library/cc138373(v=vs.90).aspx \n只需下载 WCF 示例,然后将整个 GZipMessageEncoder 项目移动到您的项目。

  2. \n
  3. 从以下链接获取 MTOMEncoder(为了清楚起见,我从 SwaEncoder 重命名了它):\n Soap-with-Attachments \n将以下类移至 GZipMessageEncoder 项目中:
    \nMimeContent、MimeParser、MimePart、MTOMEncoder

  4. \n
  5. 像这样修改 GZipMessageEncoder 类:
    \n4.1。在类的开头添加以下代码:

    \n\n
       //------------------- MTOM related stuff. Begin. ---------------------\n    const string ATTCHMNT_PROP = "attachment_file_content";\n    const string ATTCHMNT_CONTENT_ID = "Here goes content id";\n\n    private string _ContentType;\n    private string _MediaType;\n\n    protected MimeContent _MyContent;\n    protected MimePart _SoapMimeContent;\n    protected MimePart _AttachmentMimeContent;\n    protected GZipMessageEncoderFactory _Factory;\n    protected MimeParser _MimeParser;\n    private void SetupMTOM(GZipMessageEncoderFactory factory)\n    {\n        //\n        _ContentType = "multipart/related";\n        _MediaType = _ContentType;\n\n        //\n        // Create owned objects\n        //\n        _Factory = factory;\n        _MimeParser = new MimeParser();\n\n        //\n        // Create object for the mime content message\n        // \n        _SoapMimeContent = new MimePart()\n        {\n            ContentTypeStart = "application/xop+xml",\n            ContentType = "text/xml",\n            ContentId = "Here goes envelope MIME id from HTTP Content-Type header",   // TODO: make content id dynamic or configurable?\n            CharSet = "UTF-8",                                  // TODO: make charset configurable?\n            TransferEncoding = "8bit"                         // TODO: make transfer-encoding configurable?\n        };\n        _AttachmentMimeContent = new MimePart()\n        {\n            ContentType = "application/xml",                    // TODO: AttachmentMimeContent.ContentType configurable?\n            ContentId = ATTCHMNT_CONTENT_ID,                    // TODO: AttachmentMimeContent.ContentId configurable/dynamic?\n            TransferEncoding = "7bit"                         // TODO: AttachmentMimeContent.TransferEncoding dynamic/configurable?\n        };\n        _MyContent = new MimeContent()\n        {\n            Boundary = "here goes boundary id"  // TODO: MimeContent.Boundary configurable/dynamic?\n       };\n        _MyContent.Parts.Add(_SoapMimeContent);\n        _MyContent.Parts.Add(_AttachmentMimeContent);\n        _MyContent.SetAsStartPart(_SoapMimeContent);\n    }\n    //------------------- MTOM related stuff. End. ----------------------\n
    Run Code Online (Sandbox Code Playgroud)
  6. \n
\n\n

4.2. 修改方法 WriteMessage(Message message, int maxMessageSize, BufferManager bufferManager, int messageOffset) 如下:

\n\n
public override ArraySegment<byte> WriteMessage(Message message, int maxMessageSize, BufferManager bufferManager, int messageOffset)\n        {\n            ArraySegment<byte> buffer = innerEncoder.WriteMessage(message, maxMessageSize, bufferManager, 0);\n            var requestSOAPEnvelopeXml = System.Text.Encoding.UTF8.GetString(buffer.Array);\n\n            //Here you create Security node and sign the request. For ex:\n            requestSOAPEnvelopeXml = SigngEnvelope(requestSOAPEnvelopeXml);\n            //Here you are getting 1094\\1095 forms xml payload.\n            string fileContent = GetAttachmentFileContent();\n\n            //Here comes the MTOMing...\n            _SoapMimeContent.Content = System.Text.Encoding.UTF8.GetBytes(requestSOAPEnvelopeXml);\n            _AttachmentMimeContent.Content = System.Text.Encoding.UTF8.GetBytes(fileContent);\n\n            _MyContent.Parts.Where(m=> m.ContentId!=null && m.ContentId.Equals(ATTCHMNT_CONTENT_ID)).Single().ContentDisposition = GetFileName(envelope);\n            // Now create the message content for the stream\n            byte[] MimeContentBytes = _MimeParser.SerializeMimeContent(_MyContent);\n            int MimeContentLength = MimeContentBytes.Length;\n\n            // Write the mime content into the section of the buffer passed into the method\n            byte[] TargetBuffer = bufferManager.TakeBuffer(MimeContentLength + messageOffset);\n            Array.Copy(MimeContentBytes, 0, TargetBuffer, messageOffset, MimeContentLength);\n\n            // Return the segment of the buffer to the framework\n            return CompressBuffer(new ArraySegment<byte>(TargetBuffer, messageOffset, MimeContentLength), bufferManager, messageOffset);                \n        }\n
Run Code Online (Sandbox Code Playgroud)\n\n

4.3. 重写更多这样的方法:

\n\n
public override Message ReadMessage(ArraySegment<byte> buffer, BufferManager bufferManager, string contentType)\n        {\n            ArraySegment<byte> decompressedBuffer = DecompressBuffer(buffer, bufferManager);\n\n            MtomEncoder mtomEncoder = new MtomEncoder(innerEncoder, _Factory);\n            Message returnMessage = mtomEncoder.ReadMessage(buffer, bufferManager, contentType);\n            returnMessage.Properties.Encoder = mtomEncoder;\n\n            return returnMessage;\n        }\n\n        public override bool IsContentTypeSupported(string contentType)\n        {\n            return true;\n        }\n
Run Code Online (Sandbox Code Playgroud)\n\n

4.4. 确保 GZipMessage 构造函数如下所示:

\n\n
        internal GZipMessageEncoder(MessageEncoder messageEncoder, GZipMessageEncoderFactory factory)\n            : base()\n        {\n            if (messageEncoder == null)\n                throw new ArgumentNullException("messageEncoder", "A valid message encoder must be passed to the GZipEncoder");\n            innerEncoder = messageEncoder;\n\n            SetupMTOM(factory);\n        }\n
Run Code Online (Sandbox Code Playgroud)\n\n

5. 确保 GZipMessageEncodingBindingElement 类具有以下方法:

\n\n
    public override void ApplyConfiguration(BindingElement bindingElement)\n    {\n        GZipMessageEncodingBindingElement binding = (GZipMessageEncodingBindingElement)bindingElement;\n        PropertyInformationCollection propertyInfo = this.ElementInformation.Properties;\n        if (propertyInfo["innerMessageEncoding"].ValueOrigin != PropertyValueOrigin.Default)\n        {\n            switch (this.InnerMessageEncoding)\n            {\n                case "textMessageEncoding":\n                    binding.InnerMessageEncodingBindingElement = \n                        new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8);\n                    break;\n                case "binaryMessageEncoding":\n                    binding.InnerMessageEncodingBindingElement = new BinaryMessageEncodingBindingElement();\n                    break;\n            }\n        }\n    }\n
Run Code Online (Sandbox Code Playgroud)\n\n
    \n
  1. 修改 MTOMEncoder 类。确保以下方法如下所示:

    \n\n
    public override Message ReadMessage(System.IO.Stream stream, int maxSizeOfHeaders, string contentType)\n{\n    VerifyOperationContext();\n\n    if (contentType.ToLower().StartsWith("multipart/related"))\n    {\n        byte[] ContentBytes = new byte[stream.Length];\n        stream.Read(ContentBytes, 0, ContentBytes.Length);\n        MimeContent Content = _MimeParser.DeserializeMimeContent(contentType, ContentBytes);\n\n        if (Content.Parts.Count >= 1)\n        {\n            MemoryStream ms = new MemoryStream(Content.Parts[0].Content);\n            //At least for now IRS is sending SOAP envelope as 1st part(and only part(sic!) of MULTIpart response) as xml. \n            Message Msg = ReadMessage(ms, int.MaxValue, "text/xml");//Content.Parts[0].ContentType);\n\n            if( Content.Parts.Count>1 )\n                Msg.Properties.Add(ATTCHMNT_PROP, Content.Parts[1].Content);\n\n            return Msg;\n        }\n        else\n        {\n            throw new ApplicationException("Invalid mime message sent! Soap with attachments makes sense, only, with at least 2 mime message content parts!");\n        }\n    }\n    else if (contentType.ToLower().StartsWith("text/xml"))\n    {\n        XmlReader Reader = XmlReader.Create(stream);\n        return Message.CreateMessage(Reader, maxSizeOfHeaders, MessageVersion);\n    }\n    else\n    {\n        throw new ApplicationException(\n            string.Format(\n                "Invalid content type for reading message: {0}! Supported content types are multipart/related and text/xml!",\n                contentType));\n    }\n}\n
    Run Code Online (Sandbox Code Playgroud)
  2. \n
  3. GZipMessageEncoderFactory 类构造函数应如下所示:

    \n\n
       public GZipMessageEncoderFactory(MessageEncoderFactory messageEncoderFactory)\n{\n    if (messageEncoderFactory == null)\n        throw new ArgumentNullException("messageEncoderFactory", "A valid message encoder factory must be passed to the GZipEncoder");\n    encoder = new GZipMessageEncoder(messageEncoderFactory.Encoder, this);\n}\n
    Run Code Online (Sandbox Code Playgroud)
  4. \n
  5. 这就是我调用该服务的方式:

    \n\n
       var requestClient = new BulkRequestTransmitterPortTypeClient("BulkRequestTransmitterPort");\n\n        requestClient.Endpoint.Contract.ProtectionLevel = System.Net.Security.ProtectionLevel.None;\n #if DEBUG\n        var vs = requestClient.Endpoint.Behaviors.Where((i) => i.GetType().Namespace.Contains("VisualStudio"));\n        if( vs!=null )\n         requestClient.Endpoint.Behaviors.Remove((System.ServiceModel.Description.IEndpointBehavior)vs.Single());\n#endif                \n   using (var scope = new OperationContextScope(requestClient.InnerChannel))\n        {\n             //Adding proper HTTP Header to an outgoing requqest.\n            HttpRequestMessageProperty requestMessage = new HttpRequestMessageProperty();\n\n            requestMessage.Headers["Content-Encoding"] = "gzip";\n            requestMessage.Headers["Content-Type"] = @"multipart/related; type=""application/xop+xml"";start=""<Here goes envelope boundary id>"";start-info=""text/xml"";boundary=""here goes boundary id""";\n            OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = requestMessage;\n\n            response = requestClient.BulkRequestTransmitter(request.ACASecurityHeader,\n                                                                request.Security, ref request.ACABusinessHeader,\n                                                                request.ACATransmitterManifestReqDtl, \n                                                                request.ACABulkRequestTransmitter);\n        }\n
    Run Code Online (Sandbox Code Playgroud)
  6. \n
  7. 修改哑剧部分:

  8. \n
\n\n

9.1. 添加新方法:

\n\n
    public void GetHeader(StringBuilder Builder)\n    {\n        if (string.IsNullOrEmpty(ContentId) && string.IsNullOrEmpty(ContentType) && string.IsNullOrEmpty(TransferEncoding))\n            return;\n\n        if (!string.IsNullOrEmpty(ContentTypeStart))\n        {\n            Builder.Append(string.Format("Content-Type: {0}", ContentTypeStart));\n            Builder.Append(string.Format("; type=\\"{0}\\"", ContentType));\n        }\n        else\n            Builder.Append(string.Format("Content-Type: {0}", ContentType));\n\n        if (!string.IsNullOrEmpty(CharSet)) Builder.Append(string.Format("; charset={0}", CharSet));\n        Builder.Append(new char[] { \'\\r\', \'\\n\' });\n        Builder.Append(string.Format("Content-Transfer-Encoding: {0}", TransferEncoding));\n        Builder.Append(new char[] { \'\\r\', \'\\n\' });\n        Builder.Append(string.Format("Content-Id: {0}", ContentId));\n        Builder.Append(new char[] { \'\\r\', \'\\n\' });\n        if (!string.IsNullOrEmpty(ContentDisposition))\n            Builder.Append(string.Format("Content-Disposition: attachment; filename=\\"{0}\\"", ContentDisposition));\n    }\n
Run Code Online (Sandbox Code Playgroud)\n\n

9.2. 添加属性:

\n\n
   public string ContentDisposition { get; set; }\n
Run Code Online (Sandbox Code Playgroud)\n\n
    \n
  1. 修改 MimeParser SerializeMimeContent() 方法:\n替换此代码块:

    \n\n
           Builder.Append(string.Format("Content-Type: {0}", item.ContentType));\n        if (!string.IsNullOrEmpty(item.CharSet)) Builder.Append(string.Format("; charset={0}", item.CharSet));\n        Builder.Append(new char[] { \'\\r\', \'\\n\' });\n        Builder.Append(string.Format("Content-Transfer-Encoding: {0}", item.TransferEncoding));\n        Builder.Append(new char[] { \'\\r\', \'\\n\' });\n        Builder.Append(string.Format("Content-Id: {0}", item.ContentId));\n
    Run Code Online (Sandbox Code Playgroud)
  2. \n
\n\n

有了这个:

\n\n
item.GetHeader(Builder);\n
Run Code Online (Sandbox Code Playgroud)\n\n

应该就是这样!脱掉鞋子,享受忧郁!:)))

\n