我有以下操作筛选器的代码,它帮助我序列化数组,然后将其发送到FromForm绑定器,我是如何将其变成泛型的,以便我可以获得几个类类型,并将其作为T类型传递给下面的类,因此我编写了以下代码:

public class ArraySettingsOperationFilter<T> where T : IOperationFilter, new()
{
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        if (operation.RequestBody != null && operation.RequestBody.Content.TryGetValue("multipart/form-data", out var openApiMediaType))
        {
            var options = new JsonSerializerOptions { WriteIndented = true };
            var array = new OpenApiArray
         {
        new OpenApiString(JsonSerializer.Serialize(new T(),options)),
         };
            openApiMediaType.Schema.Properties["Competences"].Example = array;
        }
    }
}

在启动类中,我获取由接口标记的每个类,并将它们传递给Swagger生成器设置中的操作过滤器:

var types = typeof(IMarkerInterface)
            .Assembly.GetTypes()
            .Where(t => t.IsSubclassOf(typeof(IMarkerInterface)) && !t.IsAbstract)
            .Select(t => Activator.CreateInstance(t) as IMarkerInterface).ToList();

然后:

services.AddSwaggerGen(c =>
{
    foreach (var type in types)
    {
    c.OperationFilter<ArraySettingsOperationFilter<type>>(); //however here error says type is a variable but used like a type.
    }      
});

有人知道如何解决这个问题吗?还是变通办法?

推荐答案

嗯,c.OperationFilter<T>只是一个将FilterDescriptor添加到OperationFilterDescriptors列表中的通用扩展方法.因此,您不必依赖该泛型方法.下面这样的几个修改就可以让你达到这个目标:

首先,将泛型ArraySettingsOperationFilter更改为接受构造函数中的类型的类

public class ArraySettingsOperationFilter : IOperationFilter
{
    private readonly Type type;

    public ArraySettingsOperationFilter(Type type)
    { 
        // you can check this type implements the interface here
        this.type = type;
    }

    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        if (operation.RequestBody != null && operation.RequestBody.Content.TryGetValue("multipart/form-data", out var openApiMediaType))
        {
            var options = new JsonSerializerOptions { WriteIndented = true };
            var array = new OpenApiArray
         {
        new OpenApiString(JsonSerializer.Serialize(Activator.CreateInstance(this.type),options)),
         };
            openApiMediaType.Schema.Properties["Competences"].Example = array;
        }
    }
}

从被标记的班级中获得FilterDescriptor

 var filterDescriptors = typeof(IMarkerInterface)
        .Assembly.GetTypes()
        .Where(t => t.IsSubclassOf(typeof(IMarkerInterface)) && !t.IsAbstract)
        .Select(r => new FilterDescriptor { Type = typeof(ArraySettingsOperationFilter), Arguments = new object[] { r } })
        .ToArray();
// Arguments array will be used for instantiating ArraySettingsOperationFilter

配置Swaggergen

   builder.Services.AddSwaggerGen(c => c.OperationFilterDescriptors.AddRange(filterDescriptors));

Edit

如果您的标记类型执行相同的操作,则可以跳过实例化ArraySettingsOperationFilter.

   var filterDescriptors = typeof(IMarkerInterface)
       .Assembly.GetTypes()
       .Where(t => t.IsSubclassOf(typeof(IMarkerInterface)) && !t.IsAbstract)
       .Select(r => new FilterDescriptor { Type = r } )
       .ToArray();

Csharp相关问答推荐

C#中的包版本控制

如何使嵌套for-loop更高效?

当打印一行x个项目时,如何打印最后一行项目?

如何在NServicebus中配置学习传输的文件夹(NService bus 8)

如何使用CsvReader获取给定列索引的列标题?

如何在C#中删除一个特殊字符,如"使用Regex"

Unity 2D自顶向下弓旋转

如果属性名为xyz,我需要使用System.Text.Json修改字符串类型的值""<>

Blazor. NET 8—阶段启动配置文件不启动网站VS2022

选取器与.NET Maui MVVM的绑定属性

如何使用XmlSerializer序列化带有CDATA节的XML文件?

当索引和外键是不同的数据类型时,如何设置导航属性?

未在数据流块之间传播完成

如何在C#中转换泛型包装类内部的派生类

为什么我可以用硬编码的集合而不是变量来设置没有setter的IList属性的值?

Polly重试URL复制值

Blazor Fluent UI DialogService,<;FluentDialogProvider/>;错误

Azure函数-在外部启动类中生成配置时出错

DropDownListFor未显示选定值

如何在C#中抽象Vector256;T<;的逻辑以支持不同的硬件配置?