首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >强制IConfigurationBuilder.Bind()在对象绑定失败时抛出错误

强制IConfigurationBuilder.Bind()在对象绑定失败时抛出错误
EN

Stack Overflow用户
提问于 2019-10-09 14:42:30
回答 2查看 374关注 0票数 0

我有一个控制台应用程序,在这个应用程序中,我试图将一个配置部分绑定到这样的自定义对象类型列表中:

代码语言:javascript
运行
复制
List<myObject> myObjectList = new List<myObject>();
config.GetSection("Objects").Bind(myObjectList);
代码语言:javascript
运行
复制
public enum CustomEnum{
     One,
     Two
}

public class myObject{
    public CustomEnum myEnum { get; set; }
}

我的问题是,如果在配置文件中,您没有为该属性提供适当的枚举值(即三,而不是上面所示的一个或两个),它将无法绑定对象,并且不会抛出错误,告诉您它失败了。因此,基本上我如何使它,使我知道绑定失败,因为一个不正确的配置值?现在,它只是没有绑定那些失败的特定项目,这意味着没有真正的方法来知道有项目丢失。

成功绑定一个对象但失败并忽略另一个对象的示例配置:

代码语言:javascript
运行
复制
{
   "Objects": [
      {
         "myEnum": "One"
      },
      {
         "myEnum": "Three"
      }
   ]
}

编辑:所以对于将来发现这个问题的人来说,基本上没有很好的解决方案。您只需要手动检查,或者在配置中根本不使用枚举。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-10-09 14:52:41

在绑定对象之前“手动”验证对象。

首先将配置的值循环为字符串。查看它们是否与枚举中的现有项匹配。使用IsDefined函数。

https://learn.microsoft.com/en-us/dotnet/api/system.enum.isdefined?view=netframework-4.8

如果不抛出异常。

如果所有项都在枚举中,请像往常一样使用Bind方法。

代码语言:javascript
运行
复制
    public static bool ValidateConfig(object jsonConfig)
    {
         foreach (string item in jsonConfig) // loop through the config items as string
         {
             if (!Enum.IsDefined(typeof(CustomItem), item))
             {
                  throw new Exception("Enum value does not exist.");
             }
         }
    }
票数 0
EN

Stack Overflow用户

发布于 2019-10-09 15:04:35

基于这个帖子

ASP.NET核心配置系统非常灵活,允许您使用强类型设置。然而,部分由于这种灵活性,可能会出现只在特定环境中出现的配置错误。默认情况下,只有当代码试图使用无效的配置值(如果有的话)时,才会发现这些错误。 当应用程序启动时,您可以使用IStartupFilter来验证您的设置。这可以确保您尽快了解配置错误,而不是在运行时。

因此,首先您需要创建如下所示的interface

代码语言:javascript
运行
复制
public interface IValidatable
{
    void Validate();
}

然后:

代码语言:javascript
运行
复制
public class SettingValidationStartupFilter : IStartupFilter
{
    readonly IEnumerable<IValidatable> _validatableObjects;
    public SettingValidationStartupFilter(IEnumerable<IValidatable> validatableObjects)
    {
        _validatableObjects = validatableObjects;
    }

    public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
    {
        foreach (var validatableObject in _validatableObjects)
        {
            validatableObject.Validate();
        }

        //don't alter the configuration
        return next;
    }
}

然后,您需要向DI容器注册过滤器:

代码语言:javascript
运行
复制
public void ConfigureServices(IServiceCollection services)  
{
    services.AddTransient<IStartupFilter, SettingValidationStartupFilter>()
    // other service configuration
}

最后,您需要在要在启动时验证的设置上实现IValidatable接口:

代码语言:javascript
运行
复制
public class myObject : IValidatable
{
    public CustomEnum myEnum { get; set; }

    public void Validate()
    {
        //Do your validation here
        Validator.ValidateObject(this, new ValidationContext(this), validateAllProperties: true);
    }
}

无论使用哪种方法,如果配置和绑定存在问题,则there ()方法都会抛出异常。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58306713

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档