我有一个看似相当具体的问题。我的顶级控制器和复杂参数模型是自动生成的(Nswag)。一些模型由枚举组成。 我有必须包含反斜杠的参数(在查询或正文中)。自动生成的枚举中的这些值会自动将反斜杠替换为下划线。为了使模型验证有效,我必须以某种方式捕获与这些枚举绑定的参数并在 绑定发生之前更改它们。
例如,给定一个查询
?param=A\B
(或带有param="a\b"
的正文)和枚举:
public enum SomeEnum
{
[System.Runtime.Serialization.EnumMember(Value = @"A\B")]
A_B = 0
}
模型验证失败,因为自然不会在枚举中找到A\B
。
我已经尝试过过滤器,自定义模型绑定器等,自定义模型绑定似乎是最好的地方,因为它可以精确地应用于特定模型的绑定点。现在,问题是我需要修改传入的参数,并使用下划线绑定到修改后的版本。我一辈子都找不到解决方法。我实现了一个自定义的IModelBinder类,该类可以正确调用,但是ModelBindingResult.Success(model)
不会更改绑定到 的内容。
请明确一点,这与URL编码或绑定到集合等无关。
我基本上需要修改与特定Enum绑定的参数,以使其与自动生成的枚举属性匹配。任何想法都很感激。
答案 0 :(得分:0)
当您正确地编写代码时,自定义活页夹似乎是正确的方法...
下面是工作得很好的活页夹类。 SSASPropertyNameBinder
是枚举,其值可以包含反斜杠。此类主要来自MS ASP.Net Core文档中有关自定义模型绑定程序的样板-有趣的是最后一点。
public class SSASPropertyNameBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext == null)
{
throw new ArgumentNullException(nameof(bindingContext));
}
var modelName = bindingContext.ModelName;
// Try to fetch the value of the argument by name
var valueProviderResult = bindingContext.ValueProvider.GetValue(modelName);
if (valueProviderResult == ValueProviderResult.None)
{
return Task.CompletedTask;
}
var value = valueProviderResult.FirstValue;
// Check if the argument value is null or empty
if (string.IsNullOrEmpty(value))
{
return Task.CompletedTask;
}
ValueProviderResult newValueProviderResult = new ValueProviderResult(valueProviderResult.FirstValue.Replace(@"\", "_"));
bindingContext.ModelState.SetModelValue(modelName, newValueProviderResult);
SSASServerPropertyName spn;
// Check if a valid SSAS property
if (Enum.TryParse<SSASServerPropertyName>(newValueProviderResult.FirstValue, out spn))
{
bindingContext.Result = ModelBindingResult.Success(spn);
}
else
{
bindingContext.ModelState.TryAddModelError(modelName, $"Invalid SSAS Property: {valueProviderResult.FirstValue}");
}
return Task.CompletedTask;
}
}