ASP 芯型转换器
ASP Core type converter
我正在尝试配置 ForwardedHeadersOptions
,它是 Microsoft.AspNetCore.HttpOverrides
的一部分。我已将选项添加到 appsettings.json
"ForwardedHeadersOptions": {
"ForwardedHeaders": 5,
"ForwardLimit": 1,
"KnownProxies": [
"111.111.111.111"
]
},
前两个属性(ForwardedHeaders
和 ForwardLimit
)已正确映射,而 KnownProxies
未正确映射。这是意料之中的,因为 KnownProxies
的类型是 IList<IPAddress>
。
所以,为了映射这个 属性,我创建了类型转换器:
public class IPAddressTypeConverter : TypeConverter
{
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)
{
return base.ConvertFrom(context, culture, value);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return destinationType == typeof(IPAddress) || base.CanConvertTo(context, destinationType);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (value != null && value is string)
{
return IPAddress.Parse(value.ToString());
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
然后,我像这样在 Startup.cs
中注册了 IPAddressTypeConverter
:
public void ConfigureServices(IServiceCollection services)
{
TypeDescriptor.AddAttributes(typeof(ForwardedHeadersOptions), new TypeConverterAttribute(typeof(IPAddressTypeConverter)));
services.Configure<ForwardedHeadersOptions>(Configuration.GetSection(nameof(ForwardedHeadersOptions)));
}
但是当我启动应用程序时,类型转换器方法从未被调用。
知道这里出了什么问题吗?
当配置框架尝试转换您的 appsettings 文件中的字符串时,它会转换 FROM 字符串。您的 TypeConverter 已注册以处理它将转换为的特定类型 (IPAddress)。但它不需要测试这种类型。
[Can]ConvertTo 方法用于序列化,即从注册类型转换为另一种类型,如字符串。
因此,您的类型转换器应该类似于:
public class IPAddressTypeConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (sourceType == typeof(string) || sourceType == typeof(String))
{
return true;
}
return base.CanConvertFrom(context, sourceType);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (value != null && (value is string || value is String))
{
return IPAddress.Parse((string)value);
}
return base.ConvertFrom(context, culture, value);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(string))
{
return true;
}
return base.CanConvertTo(context, destinationType);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(string) && value is IPAddress)
{
return ((IPAddress)value).ToString();
}
return base.ConvertTo(context, culture, value, destinationType);
}
然后,在 Startup.cs、ConfigureServices() 中,为了清楚和调试断点机会,有几行:
TypeDescriptor.AddAttributes(typeof(IPAddress), new TypeConverterAttribute(typeof(IPAddressTypeConverter)));
var forwardedHeadersOptions = new ForwardedHeadersOptions();
var forwardedHeadersSection = Configuration.GetSection("ForwardedHeadersOptions");
forwardedHeadersSection.Bind(forwardedHeadersOptions);
services.Configure<ForwardedHeadersOptions>(o =>
{
o.ForwardedHeaders = ForwardedHeaders.All;
o.ForwardLimit = forwardedHeadersOptions.ForwardLimit;
foreach(var knownProxy in forwardedHeadersOptions.KnownProxies)
{
o.KnownProxies.Add(knownProxy);
}
foreach(var knownNetwork in forwardedHeadersOptions.KnownNetworks)
{
o.KnownNetworks.Add(knownNetwork);
}
});
我尝试为 KnownNetworks 制作一个类似的类型转换器,但它没有成功,可能是因为键入 (string / int)。所以我最终创建了一个单独的 IPNetworkSettingClass,其中 Prefix-field 是一个字符串而不是 IPAdress class 的对象。然后我可以使用以下方法从 appsettings 获取网络:
var knownNetworks = Configuration.GetSection("ForwardedHeadersOptions").GetSection("KnownNetworks").Get<List<IPNetworkSetting>>();
最后,我在绑定的 ForwardedHeadersOptions 实例中以编程方式设置 KnownNetworks。
希望对您有所帮助
我正在尝试配置 ForwardedHeadersOptions
,它是 Microsoft.AspNetCore.HttpOverrides
的一部分。我已将选项添加到 appsettings.json
"ForwardedHeadersOptions": {
"ForwardedHeaders": 5,
"ForwardLimit": 1,
"KnownProxies": [
"111.111.111.111"
]
},
前两个属性(ForwardedHeaders
和 ForwardLimit
)已正确映射,而 KnownProxies
未正确映射。这是意料之中的,因为 KnownProxies
的类型是 IList<IPAddress>
。
所以,为了映射这个 属性,我创建了类型转换器:
public class IPAddressTypeConverter : TypeConverter
{
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)
{
return base.ConvertFrom(context, culture, value);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return destinationType == typeof(IPAddress) || base.CanConvertTo(context, destinationType);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (value != null && value is string)
{
return IPAddress.Parse(value.ToString());
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
然后,我像这样在 Startup.cs
中注册了 IPAddressTypeConverter
:
public void ConfigureServices(IServiceCollection services)
{
TypeDescriptor.AddAttributes(typeof(ForwardedHeadersOptions), new TypeConverterAttribute(typeof(IPAddressTypeConverter)));
services.Configure<ForwardedHeadersOptions>(Configuration.GetSection(nameof(ForwardedHeadersOptions)));
}
但是当我启动应用程序时,类型转换器方法从未被调用。 知道这里出了什么问题吗?
当配置框架尝试转换您的 appsettings 文件中的字符串时,它会转换 FROM 字符串。您的 TypeConverter 已注册以处理它将转换为的特定类型 (IPAddress)。但它不需要测试这种类型。
[Can]ConvertTo 方法用于序列化,即从注册类型转换为另一种类型,如字符串。
因此,您的类型转换器应该类似于:
public class IPAddressTypeConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (sourceType == typeof(string) || sourceType == typeof(String))
{
return true;
}
return base.CanConvertFrom(context, sourceType);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (value != null && (value is string || value is String))
{
return IPAddress.Parse((string)value);
}
return base.ConvertFrom(context, culture, value);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(string))
{
return true;
}
return base.CanConvertTo(context, destinationType);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(string) && value is IPAddress)
{
return ((IPAddress)value).ToString();
}
return base.ConvertTo(context, culture, value, destinationType);
}
然后,在 Startup.cs、ConfigureServices() 中,为了清楚和调试断点机会,有几行:
TypeDescriptor.AddAttributes(typeof(IPAddress), new TypeConverterAttribute(typeof(IPAddressTypeConverter)));
var forwardedHeadersOptions = new ForwardedHeadersOptions();
var forwardedHeadersSection = Configuration.GetSection("ForwardedHeadersOptions");
forwardedHeadersSection.Bind(forwardedHeadersOptions);
services.Configure<ForwardedHeadersOptions>(o =>
{
o.ForwardedHeaders = ForwardedHeaders.All;
o.ForwardLimit = forwardedHeadersOptions.ForwardLimit;
foreach(var knownProxy in forwardedHeadersOptions.KnownProxies)
{
o.KnownProxies.Add(knownProxy);
}
foreach(var knownNetwork in forwardedHeadersOptions.KnownNetworks)
{
o.KnownNetworks.Add(knownNetwork);
}
});
我尝试为 KnownNetworks 制作一个类似的类型转换器,但它没有成功,可能是因为键入 (string / int)。所以我最终创建了一个单独的 IPNetworkSettingClass,其中 Prefix-field 是一个字符串而不是 IPAdress class 的对象。然后我可以使用以下方法从 appsettings 获取网络:
var knownNetworks = Configuration.GetSection("ForwardedHeadersOptions").GetSection("KnownNetworks").Get<List<IPNetworkSetting>>();
最后,我在绑定的 ForwardedHeadersOptions 实例中以编程方式设置 KnownNetworks。
希望对您有所帮助