枚举流利验证只接受字符串
Enum fluent validation to accept only string
下面是我的枚举
public enum IdentifierType
{
Customer = 1,
Manager = 2,
Director = 3
}
在 .Net 核心中使用流畅的验证,是否可以在请求中传递 1/"1" 或 2/"2" 或 3/"3" 时进行验证 return 验证错误?
传递“客户”或“经理”等应该没问题。
我知道在 C# 中枚举类型是 'int',但是首先考虑一下这是否可行?
startup.cs 中的设置:Validator 在我的转换器之前注册。
services.AddControllers()
.AddFluentValidation(configuration =>
{
configuration.RegisterValidatorsFromAssemblyContaining<Startup>();
})
.ConfigureApiBehaviorOptions(opt => { opt.SuppressModelStateInvalidFilter = true; })
.AddJsonOptions(serializerOption =>
{
serializerOption.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
serializerOption.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
serializerOption.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
});
API 使用邮递员的附加行为
MVC 框架必须将 JSON 转换为 class 才能使 FluentValidation 正常工作。
但是,您可以配置 MVC 以先对其进行验证。
要允许任何 ASP.NET MVC 核心应用程序中的 built-in JSON 序列化程序允许将字符串转换为枚举,您需要添加 JsonStringEnumConverter
转换器在您的应用启动时。此转换器还有一个参数,您可以将其设置为 false 以禁止使用整数值。例如:
services
.AddMvc()
.AddJsonOptions(opts =>
{
opts.JsonSerializerOptions.Converters.Add(
new JsonStringEnumConverter(allowIntegerValues: false));
})
由于 '' 似乎不会阻止将 int 作为字符串传递,因此您可以编写自己的转换器。例如,像这样的东西会起作用:
public class IdentifierTypeConverter : JsonConverter<IdentifierType>{
public override IdentifierType Read(ref Utf8JsonReader reader,
Type typeToConvert, JsonSerializerOptions options)
{
var value = reader.GetString();
if(value == null)
{
throw new Exception("No null values thanks!");
}
if(int.TryParse(value, out var _))
{
throw new Exception("No numbers thanks!");
}
return (IdentifierType)Enum.Parse(typeof(IdentifierType), value);
}
public override void Write(Utf8JsonWriter writer, IdentifierType value,
JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString());
}
}
您可以使用 JsonConverterFactory 制作通用版本。首先使转换器通用:
public class EnumConverter<TEnum> : JsonConverter<TEnum> where TEnum : Enum
{
public override bool CanConvert(Type typeToConvert) => typeToConvert.IsEnum;
public override TEnum Read(ref Utf8JsonReader reader,
Type typeToConvert, JsonSerializerOptions options)
{
var value = reader.GetString();
if (value == null)
{
throw new Exception("No null values thanks!");
}
if (int.TryParse(value, out var _))
{
throw new Exception("No numbers thanks!");
}
return (TEnum)Enum.Parse(typeof(TEnum), value);
}
public override void Write(Utf8JsonWriter writer, TEnum value,
JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString());
}
}
并让你的工厂:
public class EnumConverterFactory : JsonConverterFactory
{
public override bool CanConvert(Type typeToConvert) => typeToConvert.IsEnum;
public override JsonConverter? CreateConverter(Type typeToConvert,
JsonSerializerOptions options)
{
JsonConverter converter = (JsonConverter)Activator.CreateInstance(
typeof(EnumConverter<>).MakeGenericType(typeToConvert))!;
return converter;
}
}
现在添加工厂:
opts.JsonSerializerOptions.Converters.Add(new EnumConverterFactory());
据我所知,流畅的验证没有直接的解决方案来解决您的问题。但是,我会按如下所述处理这种情况:
在下面的代码中,我创建了两个属性 - IdentifierType
字段是 public,它将接受来自您的客户端的字符串值。另一个字段是 enum
,它可以在您的项目内部使用。
public class YourRequestModel
{
internal IdentifierType IdType
{
get
{
return Enum.Parse<IdentifierType>(IdentifierType);
}
}
public string IdentifierType { get; }
}
在进行流畅验证时,仅根据字符串值验证输入。
public class YourRequestModelValidator: AbstractValidator<YourRequestModel>
{
RuleFor(x => x.IdentifierType)
.IsEnumName(typeof(IdentifierType), caseSensitive: false);
}
下面是我的枚举
public enum IdentifierType
{
Customer = 1,
Manager = 2,
Director = 3
}
在 .Net 核心中使用流畅的验证,是否可以在请求中传递 1/"1" 或 2/"2" 或 3/"3" 时进行验证 return 验证错误?
传递“客户”或“经理”等应该没问题。
我知道在 C# 中枚举类型是 'int',但是首先考虑一下这是否可行?
startup.cs 中的设置:Validator 在我的转换器之前注册。
services.AddControllers()
.AddFluentValidation(configuration =>
{
configuration.RegisterValidatorsFromAssemblyContaining<Startup>();
})
.ConfigureApiBehaviorOptions(opt => { opt.SuppressModelStateInvalidFilter = true; })
.AddJsonOptions(serializerOption =>
{
serializerOption.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
serializerOption.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
serializerOption.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
});
API 使用邮递员的附加行为
MVC 框架必须将 JSON 转换为 class 才能使 FluentValidation 正常工作。
但是,您可以配置 MVC 以先对其进行验证。
要允许任何 ASP.NET MVC 核心应用程序中的 built-in JSON 序列化程序允许将字符串转换为枚举,您需要添加 JsonStringEnumConverter
转换器在您的应用启动时。此转换器还有一个参数,您可以将其设置为 false 以禁止使用整数值。例如:
services
.AddMvc()
.AddJsonOptions(opts =>
{
opts.JsonSerializerOptions.Converters.Add(
new JsonStringEnumConverter(allowIntegerValues: false));
})
由于 '' 似乎不会阻止将 int 作为字符串传递,因此您可以编写自己的转换器。例如,像这样的东西会起作用:
public class IdentifierTypeConverter : JsonConverter<IdentifierType>{
public override IdentifierType Read(ref Utf8JsonReader reader,
Type typeToConvert, JsonSerializerOptions options)
{
var value = reader.GetString();
if(value == null)
{
throw new Exception("No null values thanks!");
}
if(int.TryParse(value, out var _))
{
throw new Exception("No numbers thanks!");
}
return (IdentifierType)Enum.Parse(typeof(IdentifierType), value);
}
public override void Write(Utf8JsonWriter writer, IdentifierType value,
JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString());
}
}
您可以使用 JsonConverterFactory 制作通用版本。首先使转换器通用:
public class EnumConverter<TEnum> : JsonConverter<TEnum> where TEnum : Enum
{
public override bool CanConvert(Type typeToConvert) => typeToConvert.IsEnum;
public override TEnum Read(ref Utf8JsonReader reader,
Type typeToConvert, JsonSerializerOptions options)
{
var value = reader.GetString();
if (value == null)
{
throw new Exception("No null values thanks!");
}
if (int.TryParse(value, out var _))
{
throw new Exception("No numbers thanks!");
}
return (TEnum)Enum.Parse(typeof(TEnum), value);
}
public override void Write(Utf8JsonWriter writer, TEnum value,
JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString());
}
}
并让你的工厂:
public class EnumConverterFactory : JsonConverterFactory
{
public override bool CanConvert(Type typeToConvert) => typeToConvert.IsEnum;
public override JsonConverter? CreateConverter(Type typeToConvert,
JsonSerializerOptions options)
{
JsonConverter converter = (JsonConverter)Activator.CreateInstance(
typeof(EnumConverter<>).MakeGenericType(typeToConvert))!;
return converter;
}
}
现在添加工厂:
opts.JsonSerializerOptions.Converters.Add(new EnumConverterFactory());
据我所知,流畅的验证没有直接的解决方案来解决您的问题。但是,我会按如下所述处理这种情况:
在下面的代码中,我创建了两个属性 - IdentifierType
字段是 public,它将接受来自您的客户端的字符串值。另一个字段是 enum
,它可以在您的项目内部使用。
public class YourRequestModel
{
internal IdentifierType IdType
{
get
{
return Enum.Parse<IdentifierType>(IdentifierType);
}
}
public string IdentifierType { get; }
}
在进行流畅验证时,仅根据字符串值验证输入。
public class YourRequestModelValidator: AbstractValidator<YourRequestModel>
{
RuleFor(x => x.IdentifierType)
.IsEnumName(typeof(IdentifierType), caseSensitive: false);
}