Written by

Question Yone Moreno · Sep 24, 2021

Add parameter "name" inside "Content-Type" header when we send a MTOM attachment using a SOAP request

Hello,

first of all thanks for your time reading this question, and thanks for your time:

We are expected to send a file as an attachment in a SOAP request using MTOM protocol.

It is expected to include a "name" parameter inside the "Content-Type" header, as we show below:

Currently, we have developed a SOAP Operation which sends the files using MTOM protocol, however it is not including the parameter "name" inside "Content-Type" header, as you would observe:

How could we adapt it to send the parameter "name"?

Could you provide us some example or documentation?

We have read:

https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cl…

https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cl…

https://docs.intersystems.com/irisforhealthlatest/csp/docbook/DocBook.U…

What steps would you follow to develop this feature?

What is the documentation or examples we could read to achieve this?

➡️ Thanks for your time, and thanks for answering this question

EDIT: Currently our Web Client is as follows:

Class WSCLIENTE.HistoriaClinica.FicheroVacuServiceSOAP Extends %SOAP.WebClient [ ProcedureBlock ]
{

/// This is the namespace used by the Service
Parameter NAMESPACE = "http://[namespace]";

///  20/09/21 Cambiamos a 0, con el objetivo de quitar el xsi:type
Parameter OUTPUTTYPEATTRIBUTE = 0;

/// Determines handling of Security header.
Parameter SECURITYIN = "ALLOW";

/// This is the name of the Service
Parameter SERVICENAME = "FicheroVacuService";

Parameter SOAPVERSION = 1.1;

/// This is the SOAP version supported by the service.
Parameter MTOMREQUIRED = 1;

Method cargarFichero(fichero As %GlobalBinaryStream, ccaaId As EsquemasDatos.HistoriaClinica.tns.CCAAIdType(REQUIRED=1), tipoFichero As EsquemasDatos.HistoriaClinica.tns.TipoFicheroType(REQUIRED=1)) As EsquemasDatos.HistoriaClinica.tns.InfoFicheroType(XMLNAME="responseFichero") [ Final, ProcedureBlock = 1, SoapBindingStyle = document, SoapBodyUse = literal, WebMethod ]
{
  //Header - Addresing
 set addressing = ..crearAddressing()

 set addressing.Action = "cargarFichero"

 set ..AddressingOut                = addressing
 set ..AddressingOut.mustUnderstand = "1"

 set ..MTOMRequired=1
 Quit ..WebMethod("cargarFichero","CargarFicheroVacuRequest").Invoke($this,"[endpoint]/cargarFichero",.fichero,.ccaaId,.tipoFichero)
}


Method crearAddressing() As %SOAP.Addressing.Properties
{
    set IPRedSanitaria = ##class(Util.TablasMaestras).getValorMaestra("PARAMETROS","IPRedSanitaria")
     set puertoRespuestas = ##class(Util.TablasMaestras).getValorMaestra("PARAMETROS","PuertoRespuestasSSL")
     set ReplyTo = ##class(%SOAP.Addressing.EndpointReference).%New()
     set ReplyTo.Address = "http://www.w3.org/2005/08/addressing/anonymous"
     //set ReplyTo.Address = "https://"_IPRedSanitaria_":"_puertoRespuestas_"/csp/SNS/Servicios.ProgramasAsistenciales.SIFCOv02r00.cls"
     set MessageId = ##class(Util.FuncionesComunes).getUID()

     set addressing = ##class(%SOAP.Addressing.Properties).%New()
     set addressing.MessageId = MessageId
     set addressing.Destination = ..Location
     set addressing.ReplyEndpoint = ReplyTo    

     Quit addressing
}


}
$ZV: Cache for UNIX (Red Hat Enterprise Linux for x86-64) 2017.2.1 (Build 801_3_18358U) Tue Jul 24 2018 16:36:10 EDT

Comments

Sean Connelly · Sep 24, 2021

Maybe try...

set ..ContentType="application/octet-stream; name="_name
0
Yone Moreno  Sep 24, 2021 to Sean Connelly

Thanks Sean Connelly for your time and help answering to us

We have written:

Method cargarFichero(fichero As %GlobalBinaryStream, ccaaId As EsquemasDatos.HistoriaClinica.tns.CCAAIdType(REQUIRED=1), tipoFichero As EsquemasDatos.HistoriaClinica.tns.TipoFicheroType(REQUIRED=1)) As EsquemasDatos.HistoriaClinica.tns.InfoFicheroType(XMLNAME="responseFichero") [ Final, ProcedureBlock = 1, SoapBindingStyle = document, SoapBodyUse = literal, WebMethod ]
{
  //Header - Addresing
 set addressing = ..crearAddressing()
 
 set addressing.Action = "cargarFichero"
 
 set ..AddressingOut                = addressing
 set ..AddressingOut.mustUnderstand = "1"

 //Firma el XML (mensaje SOAP)
 //do ..crearSignature()
 
 set ..MTOMRequired=1
 
 //24 09 21 para añadir parametro name en cabecera content type
 set ..ContentType="application/octet-stream; name=nombre"
 
 Quit ..WebMethod("cargarFichero","CargarFicheroVacuRequest").Invoke($this,"http://ws.regvacuWs.ms.es/FicheroVacu/cargarFichero",.fichero,.ccaaId,.tipoFichero)
}

However when we output the LOGSOAP we observe:

Output from Web client with SOAP action =http:// [endpoint]/cargarFichero
----boundary2247.8235294117647062276.235294117647059--
Content-Type: application/xop+xml; type="text/xml"; charset="UTF-8"
Content-Transfer-Encoding: 8bit
Content-Id: <0.E238359C.1D35.11EC.923C.005056B672A4>

    <?xml version="1.0" encoding="UTF-8" ?>
    <SOAP-ENV:Envelope xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:s='http://www.w3.org/2001/XMLSchema' xmlns:wsa='http://www.w3.org/2005/08/addressing'>
        <SOAP-ENV:Header>
            <wsa:Action>cargarFichero</wsa:Action>
            <wsa:MessageID>e236513c1d3511ec923c005056b672a4</wsa:MessageID>
            <wsa:ReplyTo>
                <wsa:Address>http://www.w3.org/2005/08/addressing/anonymous</wsa:Address>
            </wsa:ReplyTo>
            <wsa:To>https://[endpoint]?wsdl</wsa:To>
        </SOAP-ENV:Header>
        <SOAP-ENV:Body>
            <CargarFicheroVacuRequest xmlns="http://[endpoint]">
                <fichero>
                    <xop:Include href="cid:1.E238359C.1D35.11EC.923C.005056B672A4" xmlns:xop="http://www.w3.org/2004/08/xop/include"/>
                </fichero>
                <ccaaId>01</ccaaId>
                <tipoFichero>2</tipoFichero>
            </CargarFicheroVacuRequest>
        </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>
----boundary2247.8235294117647062276.235294117647059--
Content-Id: <1.E238359C.1D35.11EC.923C.005056B672A4>
Content-Transfer-Encoding: binary
CONTENT-TYPE: application/octet-stream

;;;47B7F6BF1C6D [... csv file content ...]

As you would observe in the LOGSOAP, the request is sending the headers as: "CONTENT-TYPE: application/octet-stream"

We would need to send:

Content-Type: application/octet-stream; name=1.E238359C.1D35.11EC.923C.005056B672A4

Content-Disposition: attachment; name="1.E238359C.1D35.11EC.923C.005056B672A4"; filename="1.E238359C.1D35.11EC.923C.005056B672A4"

Because it is being expected by the receiver system, to include the parameter "name" inside the header "Content-Type", as is shown in the next image:

How could we achieve this feature?

Would you recommend us some guide or documentation, to read about this topic?

Are there any examples that could help us?

Thanks in advance

0
David Hockenbroch  Sep 24, 2021 to Yone Moreno

One of the properties of the %SOAP.WebClient class is HttpRequest which is an instance of %Net.HttpRequest. You might need to set the content type of that HttpRequest. So where you have "..ContentType", try "..HttpRequest.ContentType"?

0
Yone Moreno  Sep 27, 2021 to David Hockenbroch

Thanks David Hockenbroch for your help

We have written:

set ..HttpRequest.ContentType="application/octet-stream; name=nombre"
 do ..HttpRequest.SetHeader("name","nombre")

Being the full method as follows:

Method cargarFichero(fichero As %GlobalBinaryStream, ccaaId As EsquemasDatos.HistoriaClinica.tns.CCAAIdType(REQUIRED=1), tipoFichero As EsquemasDatos.HistoriaClinica.tns.TipoFicheroType(REQUIRED=1)) As EsquemasDatos.HistoriaClinica.tns.InfoFicheroType(XMLNAME="responseFichero") [ Final, ProcedureBlock = 1, SoapBindingStyle = document, SoapBodyUse = literal, WebMethod ]
{
  //Header - Addresing
 set addressing = ..crearAddressing()
 
 set addressing.Action = "cargarFichero"
 
 set ..AddressingOut                = addressing
 set ..AddressingOut.mustUnderstand = "1"

 //Firma el XML (mensaje SOAP)
 //do ..crearSignature()
 
 set ..MTOMRequired=1
 
 //24 09 21 para añadir parametro name en cabecera content type
 set ..ContentType="application/octet-stream; name=nombre"
 
 /*
     27 09 21 con el objetivo de poner parametro name en cabecera content type
 */
 set ..HttpRequest.ContentType="application/octet-stream; name=nombre"
 do ..HttpRequest.SetHeader("name","nombre")
 
 Quit ..WebMethod("cargarFichero","CargarFicheroVacuRequest").Invoke($this,"http://ws.regvacuWs.ms.es/FicheroVacu/cargarFichero",.fichero,.ccaaId,.tipoFichero)
}

When we execute it, Ensemble throws an exception in the message viewer:

➡️ ERROR #5001: <INVALID OREF>zcargarFichero+16^WSCLIENTE.HistoriaClinica.FicheroVacuServiceSOAP.1

We think it means that the variable "HttpRequest" is an invalid oref

How could we continue?

What steps would you recommend us to add the parameter "name" inside "Content-Type" header when we send a MTOM attachment using a SOAP request?

Thanks for your time, answers and help 💭

0