清理ASP.Net Core 2.2中的参数

时间:2018-12-29 21:53:04

标签: c# enums asp.net-core-mvc

我有一个看似相当具体的问题。我的顶级控制器和复杂参数模型是自动生成的(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绑定的参数,以使其与自动生成的枚举属性匹配。任何想法都很感激。

1 个答案:

答案 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;
    }
}