如何将appsettings.json中的字符串转换为ClaimTypes静态类对应字段值
方案1:自定义System.Text.Json转换器(默认配置场景首选)
.NET Core 3.0+默认使用System.Text.Json处理配置JSON的解析,你可以通过自定义转换器实现解析阶段自动转换:
using System.Reflection; using System.Security.Claims; using System.Text.Json; using System.Text.Json.Serialization; public class ClaimTypeJsonConverter : JsonConverter<string> { // 提前缓存ClaimTypes的所有公共常量,避免每次反射损耗 private static readonly Dictionary<string, string> _claimTypeMap = typeof(ClaimTypes) .GetFields(BindingFlags.Public | BindingFlags.Static) .Where(f => f.FieldType == typeof(string)) .ToDictionary( f => f.Name, f => (string)f.GetValue(null), StringComparer.OrdinalIgnoreCase ); public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { var input = reader.GetString(); if (string.IsNullOrWhiteSpace(input)) return input; // 匹配到常量返回对应值,匹配不到原样返回(兼容自定义ClaimType场景) return _claimTypeMap.TryGetValue(input, out var value) ? value : input; } public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options) { // 如果需要序列化时转回字段名可以在这里加反向逻辑,不需要直接写值即可 writer.WriteStringValue(value); } }
然后给OperationPolicy的ClaimType属性加转换器特性即可:
public class OperationPolicy { public string Policy { get; set; } [JsonConverter(typeof(ClaimTypeJsonConverter))] public string ClaimType { get; set; } public string ClaimValue { get; set; } }
你原来的配置绑定代码不需要做任何修改,解析时会自动完成转换。
方案2:自定义TypeConverter(全场景兼容首选)
如果需要兼容除了JSON解析之外的其他类型转换场景(比如MVC参数绑定、动态类型转换等),可以用TypeConverter实现:
using System.ComponentModel; using System.Globalization; using System.Reflection; using System.Security.Claims; public class ClaimTypeConverter : TypeConverter { private static readonly Dictionary<string, string> _claimTypeMap = typeof(ClaimTypes) .GetFields(BindingFlags.Public | BindingFlags.Static) .Where(f => f.FieldType == typeof(string)) .ToDictionary( f => f.Name, f => (string)f.GetValue(null), StringComparer.OrdinalIgnoreCase ); public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType); } public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { if (value is string input && !string.IsNullOrWhiteSpace(input)) { return _claimTypeMap.TryGetValue(input, out var res) ? res : input; } return base.ConvertFrom(context, culture, value); } }
同样给属性加特性即可:
public class OperationPolicy { public string Policy { get; set; } [TypeConverter(typeof(ClaimTypeConverter))] public string ClaimType { get; set; } public string ClaimValue { get; set; } }
两种方案都做了反射结果缓存,性能无额外损耗,且都兼容自定义ClaimType的场景,未匹配到的字段会原样返回。
内容的提问来源于stack exchange,提问作者user2871239
相关产品推荐
相关产品推荐

