设置正文

使用 set-body 策略设置请求或响应的消息正文。 可以使用 context.Request.Body 属性或 context.Response.Body 访问消息正文,具体取决于策略是在入站节中还是在出站节中。

重要

默认情况下,当用户使用 context.Request.Bodycontext.Response.Body 访问消息正文时,原始的消息正文会丢失,必须将正文返回到表达式中,以便对其进行设置。 若要保留正文内容,请在访问消息时将 preserveContent 参数设置为 true。 如果 preserveContent 设置为 true,而表达式返回了不同的正文,则会使用返回的正文。

注意

按照策略声明中提供的顺序设置策略的元素和子元素。 详细了解如何设置或编辑 API 管理策略

策略语句

<set-body template="liquid" xsi-nil="blank | null" parse-date="true | false">
    new body value as text
</set-body>

属性

属性 说明 需要 默认
template 用于更改 set-body 策略运行的模板化模式。 目前唯一支持的值是:

- liquid - set-body 策略将使用 liquid 模板引擎
空值
xsi-nil 用于控制标有 xsi:nil="true" 的元素在 XML 有效负载中的表示方式。 设置为以下值之一:

- blank - nil 用空字符串表示。
- null - nil 用 null 值表示。

不允许使用策略表达式。
blank
parse-date 布尔值。 指定是否将日期格式的字符串(例如 "/Date(1198908717056)/""2012-03-21T05:40Z")分析为 System.DateTime (mm/dd/yyyy hh:mm:ss)。 设置为 false 时,仅复制日期值。

不允许使用策略表达式。
true

对于访问请求和响应信息,Liquid 模板可绑定到具有以下属性的上下文对象:

context.
    Request.
        Url
        Method
        OriginalMethod
        OriginalUrl
        IpAddress
        MatchedParameters
        HasBody
        ClientCertificates
        Headers

    Response.
        StatusCode
        Method
        Headers
Url.
    Scheme
    Host
    Port
    Path
    Query
    QueryString
    ToUri
    ToString

OriginalUrl.
    Scheme
    Host
    Port
    Path
    Query
    QueryString
    ToUri
    ToString

使用情况

使用注意事项

  • 若要使用 set-body 策略返回全新的或更新的正文,则不需将 preserveContent 设置为 true,因为全新的正文内容是显式提供的。
  • 在传入管道中保留响应的内容是没有意义的,因为尚未响应。
  • 将请求的内容保留在出站管道中并不合理,因为请求此时已发送到后端。
  • 如果在没有消息正文的情况下使用此策略(例如在传入 GET 中使用),则会引发异常。

有关详细信息,请参阅context.Request.Body表中的 context.Request.Bodycontext.Response.BodyIMessageBody 部分。

将 Liquid 模板与 set-body 配合使用

可将 set-body 策略配置为使用 set-body 模板语言以转换请求或响应正文。 如需完全重设消息格式,则此模板非常有用。

重要

在“C# 模式”下配置 set-body 策略中使用的 Liquid 的实现。 执行筛选之类的操作时这点尤为重要。 例如,使用日期筛选器需要使用 Pascal 大小写和 C# 日期格式,如:

{{body.foo.startDateTime| Date:"yyyyMMddTHH:mm:ssZ"}}

重要

为正确绑定到使用 Liquid 模板的 XML 正文,请使用 set-header 策略将 Content-Type 设置为 application/xml、text/xml 或任何以 +xml 结尾的类型;对于 JSON 正文,其必须是 application/json、text/json 或任何以 +json 结尾的类型。

重要

Liquid 模板使用当前执行管道中的请求/响应正文作为其输入。 因此,在 return-response 策略中使用 liquid 模板不起作用。 return-response 策略会取消当前的执行管道,并删除请求/响应正文。 因此,在 return-response 中使用的任何 liquid 模板都将收到一个空字符串作为其输入,不会生成预期的输出。

支持的 Liquid 筛选器

set-body 策略支持以下 Liquid 筛选器。 有关筛选器示例,请参阅 Liquid 文档

注意

策略要求 Liquid 筛选器名称使用 Pascal 大小写(例如,“AtLeast”而不是“at_least”)。

  • Abs
  • 追加
  • AtLeast
  • AtMost
  • Capitalize
  • 精简
  • 货币
  • 日期
  • 默认
  • DividedBy
  • Downcase
  • Escape
  • First
  • H
  • 联接
  • 上一个
  • Lstrip
  • 映射
  • Minus
  • 取模
  • NewlineToBr
  • Plus
  • Prepend
  • 删除
  • RemoveFirst
  • 替换
  • ReplaceFirst
  • Round
  • Rstrip
  • 大小
  • 切片
  • 排序
  • 拆分
  • Strip
  • StripHtml
  • StripNewlines
  • 时间
  • Truncate
  • TruncateWords
  • Uniq
  • Upcase
  • UrlDecode
  • UrlEncode

示例

文字文本

<set-body>Hello world!</set-body>

访问字符串形式的正文

我们保留原始请求正文,以便稍后可以在管道中进行访问。

<set-body>
@{ 
    string inBody = context.Request.Body.As<string>(preserveContent: true); 
    if (inBody[0] =='c') { 
        inBody[0] = 'm'; 
    } 
    return inBody; 
}
</set-body>

访问 JObject 形式的正文

由于我们不保留原始请求正文,因此稍后在管道进行访问将产生异常。

<set-body> 
@{ 
    JObject inBody = context.Request.Body.As<JObject>(); 
    if (inBody.attribute == <tag>) { 
        inBody[0] = 'm'; 
    } 
    return inBody.ToString(); 
} 
</set-body>

根据产品筛选响应

以下示例演示了如何进行内容筛选,方法是:在使用 Starter 产品时删除从后端服务接收的响应中的数据元素。 示例后端响应包括类似于 OpenWeather One Call API 的根级别属性。

<!-- Copy this snippet into the outbound section to remove a number of data elements from the response received from the backend service based on the name of the product -->
<choose>
  <when condition="@(context.Response.StatusCode == 200 && context.Product.Name.Equals("Starter"))">
    <set-body>@{
        var response = context.Response.Body.As<JObject>();
        foreach (var key in new [] {"current", "minutely", "hourly", "daily", "alerts"}) {
          response.Property (key).Remove ();
        }
        return response.ToString();
      }
    </set-body>
  </when>
</choose>

使用 Liquid 模板将 JSON 转换为 SOAP

<set-body template="liquid">
    <soap:Envelope xmlns="http://tempuri.org/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
        <soap:Body>
            <GetOpenOrders>
                <cust>{{body.getOpenOrders.cust}}</cust>
            </GetOpenOrders>
        </soap:Body>
    </soap:Envelope>
</set-body>

使用 Liquid 模板转换 JSON

<set-body template="liquid">
{
"order": {
    "id": "{{body.customer.purchase.identifier}}",
    "summary": "{{body.customer.purchase.orderShortDesc}}"
    }
}
</set-body>

将正文作为 URL 编码的表单数据进行访问

以下示例使用 AsFormUrlEncodedContent() 表达式以 URL 编码的表单数据(内容类型 application/x-www-form-urlencoded)的形式访问请求正文,然后将其转换为 JSON。 由于我们不保留原始请求正文,因此稍后在管道进行访问将产生异常。

<set-body> 
@{ 
    var inBody = context.Request.Body.AsFormUrlEncodedContent();
    return JsonConvert.SerializeObject(inBody); 
} 
</set-body>

将正文作为 URL 编码的表单数据进行访问并返回

以下示例使用 AsFormUrlEncodedContent() 表达式将请求正文作为 URL 编码的表单数据(内容类型 application/x-www-form-urlencoded)进行访问、将数据添加到有效负载,并返回 URL 编码的表单数据。 由于我们不保留原始请求正文,因此稍后在管道进行访问将产生异常。

<set-body> 
@{ 
    var body = context.Request.Body.AsFormUrlEncodedContent();
    body["newKey"].Add("newValue");
    return body.ToFormUrlEncodedContent(); 
} 
</set-body>

后续步骤

有关使用策略的详细信息,请参阅: