如何在GenerateJson类型ClaimsTransformation中转义点号?
解决GenerateJson ClaimsTransformation中点号转义问题
问题描述
我编写了如下GenerateJson类型的ClaimsTransformation:
<ClaimsTransformation Id="REST-AddToGroup-JsonPayloadTransformation" TransformationMethod="GenerateJson"> <InputClaims> <InputClaim ClaimTypeReferenceId="graphUserUri" TransformationClaimType="@odata.id" /> </InputClaims> <OutputClaims> <OutputClaim ClaimTypeReferenceId="graphDataPayload" TransformationClaimType="outputClaim" /> </OutputClaims> </ClaimsTransformation>
其中graphUserUri的值类似https://graph.microsoft.com/v1.0/users/d2e7379b-f79a-4eff-af83-f7b3f3bededd。
预期生成的graphDataPayload为:
{ "@odata.id": "https://graph.microsoft.com/v1.0/users/d2e7379b-f79a-4eff-af83-f7b3f3bededd" }
但实际生成结果是嵌套结构:
{ "@odata": { "id":"https://graph.microsoft.com/v1.0/users/cd223062-d6ad-4062-8d0f-e95dfbe817c4" } }
根据文档这是预期行为,尝试用@odata\.id作为名称时,反斜杠被转义,仍生成嵌套对象,求解决办法。
解决方案
方法1:自定义ClaimsTransformation实现
内置GenerateJson会自动解析点号为嵌套对象,无法直接转义,可编写自定义转换类手动构造目标JSON:
public class CustomGenerateJsonTransformation : ClaimsTransformation { public override Task<ClaimsPrincipal> TransformAsync(ClaimsTransformationContext context) { var userUriClaim = context.Context.Claims.FirstOrDefault(c => c.Type == "graphUserUri"); if (userUriClaim != null) { var payload = $"{{\"@odata.id\": \"{userUriClaim.Value}\"}}"; context.Context.AddClaim(new Claim("graphDataPayload", payload)); } return Task.FromResult(context.Context); } }
注册该自定义转换后,在配置中替换原有的GenerateJson转换即可。
方法2:通过字符串替换修正结果
若不想编写自定义代码,可先生成嵌套JSON,再用StringReplace转换修正格式:
<!-- 生成嵌套结构的临时Payload --> <ClaimsTransformation Id="GenerateNestedJson" TransformationMethod="GenerateJson"> <InputClaims> <InputClaim ClaimTypeReferenceId="graphUserUri" TransformationClaimType="@odata.id" /> </InputClaims> <OutputClaims> <OutputClaim ClaimTypeReferenceId="tempNestedPayload" TransformationClaimType="outputClaim" /> </OutputClaims> </ClaimsTransformation> <!-- 将嵌套结构替换为目标扁平格式 --> <ClaimsTransformation Id="FixJsonFormat" TransformationMethod="StringReplace"> <InputClaims> <InputClaim ClaimTypeReferenceId="tempNestedPayload" TransformationClaimType="inputClaim" /> </InputClaims> <InputParameters> <InputParameter Id="find" Value='{"@odata": {"id":' /> <InputParameter Id="replaceWith" Value='{"@odata.id":' /> <InputParameter Id="ignoreCase" Value="false" /> </InputParameters> <OutputClaims> <OutputClaim ClaimTypeReferenceId="graphDataPayload" TransformationClaimType="outputClaim" /> </OutputClaims> </ClaimsTransformation>
需确保替换字符串与实际生成的嵌套JSON格式完全匹配(包括空格、引号等细节)。
内容的提问来源于stack exchange,提问作者Rob
相关产品推荐
相关产品推荐

