简体   繁体   中英

Azure APIM Soap Service

We use Azure APIM for hosting our SOAP services and integrating the C# code with service endpoints and making calls through HttpClient.We always create elements manually and add values to inner text of element and send it as string content to the service.This is simple for request few elements but when it comes to a huge request we have to spend lot of time in manually creating the soap xml request and is time consuming,error prone? Is there a better approach to send soap request to APIM and parse the soap reaponse?

您可以使用APIManagementARMTemplateCreator自动执行它,它为您的 API 提取 ARM 模板,以便在 CI/CD 过程中使用。

You can write the inbound policy in APIM > API operation before sending sending the request to backend soap service.

Please find the below reference.

<policies>
<inbound>
    <base />
    <rewrite-uri template="/your_soap_service_url.svc" copy-unmatched-params="false" />
    <set-body template="none">@{
          string message = context.Request.Body.As<String>(preserveContent:true);
            try
            {
                 you can write your logic here, if you want to manipulale your request

            }
            catch{}

           string soapPacketStart = "<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:yourNamespace=\"namespace url, if you have namespace in your message">
                <soap:Header xmlns:wsa=\"http://www.w3.org/2005/08/addressing\">
                    <wsa:Action>YourAction</wsa:Action>
                    <wsa:To>https://your_backend_url.svc</wsa:To>
                </soap:Header>
                <soap:Body>";
            string soapPacketEnd ="</soap:Body>
            </soap:Envelope>";
            message = string.Format("{0}{1}{2}",soapPacketStart,message,soapPacketEnd); //your soap message is ready
            return message;
        }</set-body>
        <set-header name="Content-Type" exists-action="override">
            <value>application/soap+xml; Action="YourAction"</value>
        </set-header>
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
                //like wise you can set your response
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>

You can define your SOAP-request body in an liquid template and parse the XML-response and convert it back to json like in this example:

<policies>
    <inbound>
        <base />
        <set-header name="Content-Type" exists-action="override">
            <value>text/xml;charset=UTF-8</value>
        </set-header>
        <set-method>POST</set-method>
        <set-body template="liquid">
            <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tim="http://services.test.com/Service">
                <soapenv:Header />
                <soapenv:Body>
                    <tim:GetTimesheet>
                        <tim:input>
                            <tim:DateTimeFrom>{{context.Request.MatchedParameters["DateTimeFrom"]}}</tim:DateTimeFrom>
                            <tim:DateTimeTo>{{context.Request.MatchedParameters["DateTimeTo"]}}</tim:DateTimeTo>
                            <tim:ResourceId>{{context.Request.MatchedParameters["ResourceId"]}}</tim:ResourceId>
                        </tim:input>
                    </tim:GetTimesheet>
                </soapenv:Body>
            </soapenv:Envelope>
        </set-body>
        <set-backend-service base-url="https://webservices/service.svc" />
        <rewrite-uri template="/" copy-unmatched-params="false" />
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
        <xsl-transform>
            <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
                <xsl:output method="xml" indent="yes" />
                <xsl:template match="* | @* | node()">
                    <xsl:apply-templates select="@* | node()|*" />
                </xsl:template>
                <xsl:template match="PeriodList">
                    <item>
                        <xsl:for-each select="PeriodType">
                            <timeSheet>
                                <DateTimeFrom>
                                    <xsl:value-of select="*[local-name() = 'DateFrom']" />
                                </DateTimeFrom>
                                <DateTimeTo>
                                    <xsl:value-of select="*[local-name() = 'DateTo']" />
                                </DateTimeTo>
                                <Status>
                                    <xsl:value-of select="*[local-name() = 'Status']" />
                                </Status>
                                <EntryList>
                                    <xsl:for-each select="EntryList/Entry/WorkDayList/WorkDay">
                                        <Entry>
                                            <Day>
                                                <xsl:value-of select="Day" />
                                            </Day>
                                            <HoursWorked>
                                                <xsl:value-of select="HoursWorked" />
                                            </HoursWorked>
                                        </Entry>
                                    </xsl:for-each>
                                </EntryList>
                            </timeSheet>
                        </xsl:for-each>
                    </item>
                </xsl:template>
            </xsl:stylesheet>
        </xsl-transform>
        <set-body template="liquid">
        [
        {%- JSONArrayFor ts in body.item -%}        
        {
            "dateTimeFrom" : "{{ts.timeSheet.DateTimeFrom}}",
            "dateTimeTo" : "{{ts.timeSheet.DateTimeTo}}",
            "periodId" : "{{ts.timeSheet.PeriodId}}",
            "days": [
                    {%- JSONArrayFor wd in ts.timeSheet.EntryList -%}   
                    {
                        "day" : "{{wd.Entry.Day}}",
                        "hoursWorked" : "{{wd.Entry.HoursWorked}}"
                    }
                    {%- endJSONArrayFor -%}
                    ]
        }
        {%- endJSONArrayFor -%}
        ]
        </set-body>
        <set-header name="Content-Type" exists-action="override">
            <value>application/json</value>
        </set-header>
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM