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. 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. 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. I want to create a SchemaProcessor that remaps this AppRequestOfUser to 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. I do not want to use a discriminator property. I want to remap to the appropriate concrete type.