fix
All checks were successful
Build and Deploy / deploy (push) Successful in 48s

This commit is contained in:
xiaolipro 2026-10-12 10:47:29 +08:00
parent 142e8ff441
commit d8ae8a76ba
3 changed files with 76 additions and 12 deletions

View File

@ -421,7 +421,8 @@ public class DefaultForwardFlow : IForwardFlow, ITransientDependency
Dictionary<string, string> nameValueCollection; Dictionary<string, string> nameValueCollection;
if (context.FormFieldList.Count != 0) if (context.FormFieldList.Count != 0)
{ {
var field = context.FormFieldList.FirstOrDefault(x => x.Value == GlobalConst.FromMappingBody); var field = context.FormFieldList.FirstOrDefault(x =>
x.Value is GlobalConst.FromMappingBody or GlobalConst.FromBody);
if (field != null) field.Value = body; if (field != null) field.Value = body;
nameValueCollection = context.FormFieldList.ToDictionary(x => x.Name, x => x.Value); nameValueCollection = context.FormFieldList.ToDictionary(x => x.Name, x => x.Value);
} }
@ -532,17 +533,18 @@ public class DefaultForwardFlow : IForwardFlow, ITransientDependency
// Query / Header / 表单 // Query / Header / 表单
foreach (var item in context.QueryFieldList) foreach (var item in context.QueryFieldList)
{ {
item.Value = ReplaceFormPlaceholder(item.Name, item.Value, item.Description); item.Value = ReplaceFormPlaceholder(item.Name, item.Value, item.Description, keepMappingBodyPlaceholder: false);
} }
foreach (var item in context.HeaderFieldList) foreach (var item in context.HeaderFieldList)
{ {
item.Value = ReplaceFormPlaceholder(item.Name, item.Value, item.Description); item.Value = ReplaceFormPlaceholder(item.Name, item.Value, item.Description, keepMappingBodyPlaceholder: false);
} }
foreach (var item in context.FormFieldList) foreach (var item in context.FormFieldList)
{ {
item.Value = ReplaceFormPlaceholder(item.Name, item.Value, item.Description); // FormUrlEncoded 的 Body KV 保留占位符,交由 SetContentType 用序列化后的 TargetInterfaceInput 填充
item.Value = ReplaceFormPlaceholder(item.Name, item.Value, item.Description, keepMappingBodyPlaceholder: true);
} }
// 绑定body部分的字段 // 绑定body部分的字段
@ -578,7 +580,7 @@ public class DefaultForwardFlow : IForwardFlow, ITransientDependency
} }
} }
string ReplaceFormPlaceholder(string name, string value, string? description) string ReplaceFormPlaceholder(string name, string value, string? description, bool keepMappingBodyPlaceholder)
{ {
return value switch return value switch
{ {
@ -589,9 +591,11 @@ public class DefaultForwardFlow : IForwardFlow, ITransientDependency
GlobalConst.DateTime => TurnDate(now, description), GlobalConst.DateTime => TurnDate(now, description),
GlobalConst.Url => context.TargetInterface.RequestAddress, GlobalConst.Url => context.TargetInterface.RequestAddress,
GlobalConst.FromAccount => context.GetAccountFieldValueOrNull(name) ?? string.Empty, GlobalConst.FromAccount => context.GetAccountFieldValueOrNull(name) ?? string.Empty,
GlobalConst.FromMappingBody => context.TargetInterface.ContentType == ContentType.FormUrlEncoded // Body 表单在 FormUrlEncoded 时保留占位符;Query/Header 必须立刻展开,否则会原样发出
? GlobalConst.FromMappingBody GlobalConst.FromMappingBody or GlobalConst.FromBody =>
: JsonConvert.SerializeObject(context.OriginalInterfaceMappedInput), keepMappingBodyPlaceholder && context.TargetInterface.ContentType == ContentType.FormUrlEncoded
? GlobalConst.FromMappingBody
: JsonConvert.SerializeObject(context.OriginalInterfaceMappedInput),
_ => value _ => value
}; };
} }

View File

@ -108,10 +108,7 @@ public class InterfaceService : ApplicationService
// 构造参数 // 构造参数
var paras = await InterfaceRepository.GetParameterListByIdAsync(id); var paras = await InterfaceRepository.GetParameterListByIdAsync(id);
// 入参树形列表
res.InParameterList = interfaceEntity.IsUpStream
? paras.Where(x => x.IsInPara && x.ParaKind == ParameterParaKind.Normal).ToList()
: [];
res.RequestBodyParameterList = !interfaceEntity.IsUpStream && interfaceEntity.ContentType is ContentType.Json or ContentType.Xml res.RequestBodyParameterList = !interfaceEntity.IsUpStream && interfaceEntity.ContentType is ContentType.Json or ContentType.Xml
? paras.Where(x => x.IsInPara && x.ParaKind == ParameterParaKind.Normal).ToList() ? paras.Where(x => x.IsInPara && x.ParaKind == ParameterParaKind.Normal).ToList()
: []; : [];

View File

@ -96,6 +96,69 @@ public class DefaultForwardFlowTests
Assert.Equal("{\"orderId\":\"A001\"}", Assert.Single(context.QueryFieldList).Value); Assert.Equal("{\"orderId\":\"A001\"}", Assert.Single(context.QueryFieldList).Value);
} }
[Fact]
public void ReplacePlaceholder_ShouldExpandQueryFromMappingBodyForFormUrlEncoded()
{
var flow = new TestForwardFlow();
var context = new ForwardCoreContext
{
TargetInterface = new InterfaceDto
{
ContentType = ContentType.FormUrlEncoded,
RequestAddress = "https://example.com/openapi"
},
OriginalInterfaceMappedInput = new JObject { ["orderId"] = "A001" },
QueryFieldList =
[
new InterfaceFormFieldDto
{
Name = "bizData",
Value = GlobalConst.FromMappingBody
}
],
FormFieldList =
[
new InterfaceFormFieldDto
{
Name = "notifyBizEventDTO",
Value = GlobalConst.FromMappingBody
}
]
};
flow.ReplacePlaceholder(context);
Assert.Equal("{\"orderId\":\"A001\"}", Assert.Single(context.QueryFieldList).Value);
Assert.Equal(GlobalConst.FromMappingBody, Assert.Single(context.FormFieldList).Value);
}
[Fact]
public void ReplacePlaceholder_ShouldExpandLegacyFromBodyInQuery()
{
var flow = new TestForwardFlow();
var context = new ForwardCoreContext
{
TargetInterface = new InterfaceDto
{
ContentType = ContentType.FormUrlEncoded,
RequestAddress = "https://example.com/openapi"
},
OriginalInterfaceMappedInput = new JObject { ["orderId"] = "A001" },
QueryFieldList =
[
new InterfaceFormFieldDto
{
Name = "bizData",
Value = GlobalConst.FromBody
}
]
};
flow.ReplacePlaceholder(context);
Assert.Equal("{\"orderId\":\"A001\"}", Assert.Single(context.QueryFieldList).Value);
}
class TestForwardFlow : DefaultForwardFlow class TestForwardFlow : DefaultForwardFlow
{ {
public void SetContentTypeForTest(ForwardCoreContext context, HttpRequestMessage message) public void SetContentTypeForTest(ForwardCoreContext context, HttpRequestMessage message)