[英]Enum fluent validation to accept only string
下面是我的枚舉
public enum IdentifierType
{
Customer = 1,
Manager = 2,
Director = 3
}
在 .Net 核心中使用流暢的驗證,是否可以在請求中傳遞 1/"1" 或 2/"2" 或 3/"3" 時返回驗證錯誤進行驗證?
通過“客戶”或“經理”等應該可以正常工作。
我知道 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 使用 postman 的附加行為
MVC 框架必須將 JSON 轉換為 class,FluentValidation 才能工作。
但是,您可以配置 MVC 以首先驗證它。
要允許任何 ASP.NET MVC Core 應用程序中的內置 JSON 序列化程序允許將字符串轉換為枚舉,您需要在應用程序啟動時添加JsonStringEnumConverter
轉換器。 此轉換器還有一個參數,您可以將其設置為 false 以禁止 integer 值。 例如:
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
字段是公共的,它將接受來自您的客戶端的字符串值。 另一個字段是一個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);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.