数组中的配置绑定异常未被捕获



配置中数组的异常未通过?!对于一维配置,这是可行的(如您所见(。但是,当使用更多维度配置时,异常将被忽略,如您在以下示例中所见:

appsettings.json

{
"Value": 1,
"ArrayValue": [
{ "Value":  0 }
]
}

配置

class Config
{
private int value;
public int Value
{
get => this.value;
set
{
if (value < 1)
throw new NullReferenceException();     // ExceptionType only for testing purpose
this.value = value;
}
}
public IEnumerable<ConfigArray> ArrayValue { get; set; }
}
class ConfigArray
{
private int arrayValue;
public int ArrayValue
{
get => this.arrayValue;
set
{
if (value < 1)
throw new NullReferenceException();     // ExceptionType only for testing purpose
this.arrayValue = value;
}
}
}

程序片段

Config config;
try
{
IConfigurationRoot configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", false, false)
.Build();
config = configuration.Get<Config>();
//config = new Config();
//configuration.Bind(config);
}
catch (Exception ex)
{
Console.WriteLine($"Exception: {ex.Message}");
}

包裹

<PackageReference Include="Microsoft.Extensions.Configuration" Version="3.1.6" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="3.1.6" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.6" />

ConfigArray中的异常不会绕过主程序。是我遗漏了什么,还是数组中的异常通常被配置绑定器忽略了?

我找到的一个可能的解决方案是创建一个属性来确定是否发生错误。

可能的解决方案:

配置

// If more than one error is possible, it can be a better solution to generate error codes
enum ErrorCode
{
OK,
ERROR
}
class Config
{
private int value;
private IEnumerable<ConfigArray> configArray;
public int Value
{
get => this.value;
set
{
if (value < 1)
throw new NullReferenceException();     // ExceptionType only for testing purpose
this.value = value;
}
}

public IEnumerable<ConfigArray> ArrayValue
{
get => this.configArray;
set
{
value.ToList().ForEach(c =>
{
switch (c.Error)
{
case ErrorCode.ERROR:
throw new NullReferenceException();
default:
break;
}   
});
this.configArray = value;
}
}
}
class ConfigArray
{
private int arrayValue;
public int ArrayValue
{
get => this.arrayValue;
set
{
this.Error = ErrorCode.OK;
if (value < 1)
this.Error = ErrorCode.ERROR;
this.arrayValue = value;
}
}
public ErrorCode Error { get; private set; }
}

程序代码段

Config config = null;
try
{
IConfigurationRoot configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", false, false)
.Build();
config = configuration.Get<Config>();
//config = new Config();
//configuration.Bind(config);
}
catch (Exception ex)
{
if(ex.InnerException is Exception)
Console.WriteLine($"Inner Exception: {ex.InnerException.Message}");
Console.WriteLine($"Exception: {ex.Message}");
}

也许还有更好的解决方案?

有关详细信息,请参阅此处。Microsoft.Extension.Configuration.Binder/src/ConfigurationBinder.cs

private static Array BindArray(Array source, IConfiguration config, BinderOptions options)
{
IConfigurationSection[] children = config.GetChildren().ToArray();
int arrayLength = source.Length;
Type elementType = source.GetType().GetElementType();
var newArray = Array.CreateInstance(elementType, arrayLength + children.Length);
// binding to array has to preserve already initialized arrays with values
if (arrayLength > 0)
{
Array.Copy(source, newArray, arrayLength);
}
for (int i = 0; i < children.Length; i++)
{
try
{
object item = BindInstance(
type: elementType,
instance: null,
config: children[i],
options: options);

if (item != null)
{
newArray.SetValue(item, arrayLength + i);
}
}
catch
{
}
}
return newArray;
}

正如您在上面的代码中所看到的,我们捕获并抓住了异常。因此,有必要采取类似sunriax所采取的行动。

最新更新