简体   繁体   English

清理ASP.Net Core 2.2中的参数

[英]Sanitising parameters in ASP.Net Core 2.2

I have a seemingly rather specific problem. 我有一个看似相当具体的问题。 My top-level controller and models for complex parameters are auto-generated (Nswag). 我的顶级控制器和复杂参数模型是自动生成的(Nswag)。 Some of the model consists of enums. 一些模型由枚举组成。 I have parameters (in query or body) which have to contain backslashes. 我有必须包含反斜杠的参数(在查询或正文中)。 The values of these in the auto-generated enums automatically have backslashes replaced with underscores. 自动生成的枚举中的这些值会自动将反斜杠替换为下划线。 To make model validation work, I have to somehow catch parameters binding with these enums and change them before binding occurs therefore. 为了使模型验证有效,我必须以某种方式捕获与这些枚举绑定的参数,并绑定发生之前更改它们。

For example, given a query 例如,给定一个查询

?param=A\\B

(or a body with param="a\\b" ) and the Enum: (或带有param="a\\b"的主体)和枚举:

public enum SomeEnum
{
  [System.Runtime.Serialization.EnumMember(Value = @"A\B")]
  A_B = 0
}

Model validation fails because A\\B isn't found in the enum, naturally. 模型验证失败,因为自然会在枚举中找不到A\\B

I have tried filters, custom model binders etc. and custom model binding seems to be the best place as it can be made to apply at precisely the point of binding that specific model. 我尝试过过滤器,自定义模型绑定器等,自定义模型绑定似乎是最好的地方,因为它可以精确地应用于绑定该特定模型的位置。 Now, the problem is that I need to modify the incoming parameter and bind to a modified version with underscores. 现在,问题是我需要修改传入的参数,并使用下划线绑定到修改后的版本。 I can't for the life of me find out how to do this. 我一辈子都找不到解决方法。 I implemented a custom IModelBinder class, which is called properly but ModelBindingResult.Success(model) doesn't alter what is bound to . 我实现了一个自定义IModelBinder类,该类可以正确调用,但ModelBindingResult.Success(model)不会更改绑定到的对象

Just to be clear, this has nothing to do with URL encoding or binding to collections etc. This is all working fine. 只需清楚一点,这与URL编码或绑定到集合等无关。这一切都很好。

I essentially need to modify parameters being bound with a specific Enum so that they match the auto-generated enum properties. 我本质上需要修改与特定Enum绑定的参数,以使其与自动生成的枚举属性匹配。 Any ideas much appreciated. 任何想法表示赞赏。

It seems that a custom binder is the correct way to do it, when you code it properly ... Below is the binder class that works nicely. 似乎,自定义活页夹是正确进行编码的正确方法。下面是活页夹类,可以很好地工作。 SSASPropertyNameBinder is the enum whose values can contain backslashes. SSASPropertyNameBinder是其值可以包含反斜杠的枚举。 This class is mostly boiler plate from the MS ASP.Net Core docs on custom model binders - the interesting bit is at the end. 此类主要来自于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;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM