简体   繁体   English

如何使用NJsonSchema更改属性的类型

[英]How can I change the type of a property with NJsonSchema

I have a series of generic response objects that are being returned with a property that is an abstract class. 我有一系列通用响应对象,这些对象带有一个抽象类的属性返回。 The NSwag and NJsonSchema generate the schema with an abstract class, which creates problems. NSwag和NJsonSchema生成带有抽象类的架构,这会产生问题。 The concrete class is easily determined via reflection, however, there does not seem to be a clean way to get NJsonSchema to replace the abstract type with the appropriate concrete one. 具体的类很容易通过反射来确定,但是,似乎没有一种干净的方法来使NJsonSchema用适当的具体类来代替抽象类型。 What is the correct way to do this? 正确的方法是什么?

public abstract class AppRequest<TData> {
    public Guid RequestId { get; set; }
}

public class AppResponse<TData> {
    public TData Data { get; set; }
    public AppRequest<TData> OriginalRequest { get; set; }
}

public class User {
....
}

public class UserRequest: AppRequest<User> {
    public Guid UserId { get; set; }
}

NSwag generates response object as AppResponseOfUser which is fine, however, it says that the OriginalRequest property is AppRequestOfUser and that it is abstract. NSwag生成响应对象为AppResponseOfUser ,这很好,但是,它说OriginalRequest属性是AppRequestOfUser,并且它是抽象的。 I want to create a SchemaProcessor that remaps this AppRequestOfUser to UserRequest. 我想创建一个SchemaProcessor来将此AppRequestOfUser重新映射到UserRequest。 Something like this: 像这样:

public class MySchemaProcessor
    : ISchemaProcessor
{
    public async Task ProcessAsync(SchemaProcessorContext context)
    {
        if (context.Type.IsGenericOf(typeof(AppResponse<>)))
        {
            var modelType = context.Type.GenericTypeArguments[0];
            var abstractRequestType = typeof(AppRequest<>).MakeGenericType(modelType);

            var actualRequestType = modelType.Assembly.GetTypes()
                .Single(t => t.IsClass && t.BaseType == abstractRequestType);

            var requestSchema = await JsonSchema4.FromTypeAsync(actualRequestType);

            var originalRequestProperty = context.Schema.Properties["originalRequest"];
            originalRequestProperty.IsReadOnly = true;
            originalRequestProperty.IsAbstract = false;

            // CHANGE PROPERTY TYPE HERE!!!
        }
    }
}

Unfortunately, NJsonSchema doesn't seem to be very flexible and there is no clear way on how to do this. 不幸的是,NJsonSchema似乎并不十分灵活,并且没有明确的方法来做到这一点。 I do not want to use a discriminator property. 我不想使用鉴别属性。 I want to remap to the appropriate concrete type. 我想重新映射到适当的具体类型。

In case anyone was wondering, here is the final solution: 如果有人想知道,这里是最终的解决方案:

var classesToMap = typeof(Startup)
                .Assembly
                .GetTypes()
                .Where(t => t.IsClass && t.BaseType.IsGenericOf(typeof(AppRequest<>)));

            var settings = new JsonSchemaGeneratorSettings()
            {
                FlattenInheritanceHierarchy = true,

            };
            foreach (var type in classesToMap)
            {
                var actualSchema = JsonSchema4.FromTypeAsync(type,settings).Result;
                options.TypeMappers.Add(new ObjectTypeMapper(type.BaseType, actualSchema));
            }

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

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