You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure APIM策略问题:提取匹配请求HostHeader的JSON数组值

修正Azure APIM策略:匹配X-Forwarded-Host头并提取对应value值

错误根源

  1. 外部URL返回的是JSON数组,但原策略错误将其解析为JObject类型
  2. 缓存存储时把对象转成了字符串,后续读取缓存后直接尝试将字符串强制转为JArray/JObject,触发类型转换异常

修正后的完整策略

<inbound>
    <cache-lookup-value key="hostnames" variable-name="hostnames" />
    <choose>
        <when condition="@(!context.Variables.ContainsKey("hostnames"))">
            <send-request mode="new" response-variable-name="response" timeout="20" ignore-error="true">
                <set-url>@($"https://gist.githubusercontent.com/artisticcheese/b72ecad52e5c6804c7f0e81dd0344dc7/raw/908bf7f93891674ca665d3c4982a02de43b6ed6f/gistfile1.txt")</set-url>
                <set-method>GET</set-method>
            </send-request>
            <!-- 修正:将响应解析为JArray(原返回是JSON数组) -->
            <set-variable name="hostnames" value="@(((IResponse)context.Variables["response"]).Body.As<JArray>())" />
            <!-- 直接存储JArray对象,无需转字符串 -->
            <cache-store-value key="hostnames" value="@((JArray)context.Variables["hostnames"])" duration="100000" />
        </when>
    </choose>
    <!-- 增加空值判断,避免X-Forwarded-Host头不存在时的异常 -->
    <set-variable name="requestHostname" value="@(context.Request.Headers.ContainsKey("X-Forwarded-Host") ? context.Request.Headers["X-Forwarded-Host"].First() : string.Empty)" />
    <set-variable name="matching_value" value="@{ 
        var jsonArray = (JArray)context.Variables["hostnames"];
        var incomingHost = (string)context.Variables["requestHostname"];
        
        // 匹配对应的hostname条目,提取value值
        var matchedEntry = jsonArray.FirstOrDefault(entry => 
            string.Equals((string)entry["hostname"], incomingHost, StringComparison.OrdinalIgnoreCase));
        
        // 无匹配时返回默认值0,可根据需求调整
        return matchedEntry != null ? (int)matchedEntry["value"] : 0;
    }" />
    <return-response>
        <set-status code="200" reason="OK" />
        <set-header name="Content-Type" exists-action="override">
            <value>application/json</value>
        </set-header>
        <!-- 返回匹配到的value值 -->
        <set-body>@{ 
            var matchedValue = (int)context.Variables["matching_value"];
            return JsonConvert.SerializeObject(new { matched_value = matchedValue });
        }</set-body>
    </return-response>
    <base />
</inbound>

关键改动说明

  • 响应解析修正:将Body.As<JObject>()改为Body.As<JArray>(),匹配外部返回的JSON数组结构
  • 缓存逻辑优化:直接缓存JArray对象,避免字符串与JSON对象之间的转换开销和类型错误
  • 边界处理增强:获取X-Forwarded-Host头时增加存在性判断,避免空引用异常;无匹配条目时返回默认值
  • 结果提取优化:直接返回匹配条目的value字段(而非整个条目),符合需求场景

内容的提问来源于stack exchange,提问作者Gregory Suvalian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 20:55:14