Open rhegner opened 3 years ago
Did you try [KnownType("AdditionalType")]
?
And where do I add this attribute? On any of my controllers?
(My current workaround is to create a dummy endpoint which uses the additional type).
You can also programmatically add additional schemas in PostProcess or a document processor with the schema generator in the context object.
Did you try
[KnownType("AdditionalType")]
?
Decorating class Foo
with [KnownType("Foo")]
does not result in exported type (when using TypeScript client generator)
It's [KnownType(typeof(Foo))] on an exposed class Bar
It's [KnownType(typeof(Foo))] on an exposed class Bar
What if Bar
does not inherit Foo
? How to export stand-alone type that is not referenced by any of the Web API controllers - is it possible?
I think that doesnt matter, its just a way to tell the gen to include it.. its not used as inheritance.
Otherwise:
You can also programmatically add additional schemas in PostProcess or a document processor with the schema generator in the context object.
I think that doesnt matter, its just a way to tell the gen to include it.. its not used as inheritance.
I tried this:
[KnownType(typeof(Foo))]
public class Foo
{
[JsonConstructor]
public Foo(string name)
{
this.name = name;
}
public readonly string name;
}
And it does not produce any additional output.
Otherwise:
You can also programmatically add additional schemas in PostProcess or a document processor with the schema generator in the context object.
I don't understand what this means.
api.nswag
file:
{
"runtime": "Net50",
"defaultVariables": null,
"documentGenerator": {
"webApiToOpenApi": {
"controllerNames": [],
"isAspNetCore": true,
"resolveJsonOptions": false,
"defaultUrlTemplate": "api/{controller}/{action}/{id?}",
"addMissingPathParameters": false,
"includedVersions": null,
"defaultPropertyNameHandling": "CamelCase",
"defaultReferenceTypeNullHandling": "NotNull",
"defaultDictionaryValueReferenceTypeNullHandling": "NotNull",
"defaultResponseReferenceTypeNullHandling": "NotNull",
"defaultEnumHandling": "Integer",
"flattenInheritanceHierarchy": false,
"generateKnownTypes": true,
"generateEnumMappingDescription": false,
"generateXmlObjects": false,
"generateAbstractProperties": false,
"generateAbstractSchemas": true,
"ignoreObsoleteProperties": false,
"allowReferencesWithProperties": false,
"excludedTypeNames": [],
"serviceHost": null,
"serviceBasePath": null,
"serviceSchemes": [],
"infoTitle": "My Title",
"infoDescription": null,
"infoVersion": "1.0.0",
"documentTemplate": null,
"documentProcessorTypes": [],
"operationProcessorTypes": [],
"typeNameGeneratorType": null,
"schemaNameGeneratorType": null,
"contractResolverType": null,
"serializerSettingsType": null,
"useDocumentProvider": true,
"documentName": "v1",
"aspNetCoreEnvironment": null,
"createWebHostBuilderMethod": null,
"startupType": null,
"allowNullableBodyParameters": true,
"output": null,
"outputType": "Swagger2",
"assemblyPaths": [
"MyProject/bin/$(Configuration)/$(TargetFramework)/MyProject.Api.dll"
],
"assemblyConfig": null,
"referencePaths": [],
"useNuGetCache": false
}
},
"codeGenerators": {
"openApiToTypeScriptClient": {
"className": "{controller}Client",
"moduleName": "",
"namespace": "",
"typeScriptVersion": 2.0,
"template": "Fetch",
"promiseType": "Promise",
"httpClass": "Http",
"withCredentials": false,
"useSingletonProvider": false,
"injectionTokenType": "OpaqueToken",
"rxJsVersion": 6.0,
"dateTimeType": "String",
"nullValue": "Undefined",
"generateClientClasses": true,
"generateClientInterfaces": false,
"generateOptionalParameters": true,
"exportTypes": true,
"wrapDtoExceptions": false,
"exceptionClass": "SwaggerException",
"clientBaseClass": null,
"wrapResponses": false,
"wrapResponseMethods": [],
"generateResponseClasses": true,
"responseClass": "SwaggerResponse",
"protectedMethods": [],
"configurationClass": null,
"useTransformOptionsMethod": false,
"useTransformResultMethod": false,
"generateDtoTypes": true,
"operationGenerationMode": "MultipleClientsFromOperationId",
"markOptionalProperties": true,
"generateCloneMethod": false,
"typeStyle": "Interface",
"classTypes": [],
"extendedClasses": [],
"extensionCode": null,
"generateDefaultValues": true,
"excludedTypeNames": [],
"excludedParameterNames": [],
"handleReferences": false,
"generateConstructorInterface": true,
"convertConstructorInterfaceData": false,
"importRequiredTypes": false,
"useGetBaseUrlMethod": false,
"baseUrlTokenName": "API_BASE_URL",
"queryNullValue": "",
"inlineNamedDictionaries": false,
"inlineNamedAny": false,
"templateDirectory": "Templates/$(Template)",
"typeNameGeneratorType": null,
"propertyNameGeneratorType": null,
"enumNameGeneratorType": null,
"serviceHost": null,
"serviceSchemes": null,
"output": "Client/api/$(Template).ts"
}
}
}
.csproj
file:
<!-- Generate TypeScript type wrappers. -->
<Target Name="NSwagClients" AfterTargets="Build">
<Exec Command="$(NSwagExe_Net50) run api.nswag /variables:TargetFramework=$(TargetFramework),Configuration=$(Configuration),Template=Types" />
</Target>
This setup results in two `.ts` files:
- `Types.ts`
- `Clients.ts`
I have custom templates for both. What would I need to change in order for `Foo` to be added as output for `Types.ts`?
Here's an example processor for those who would like to use one.
/// <summary>
/// Registers additional types that cannot be directly seen from Web API, like SignalR messages.
/// </summary>
public sealed class AddAdditionalTypeProcessor<T>: IDocumentProcessor where T : class
{
public void Process(DocumentProcessorContext context)
{
context.SchemaResolver.AddSchema(typeof(T), isIntegerEnumeration: false, JsonSchema.FromType<T>());
}
}
And usage:
services.AddSwaggerDocument(settings =>
{
settings.DocumentProcessors.Add(new AddAdditionalTypeProcessor<MyTypeToExport>());
});
How to do this for Owin WebApi?
Here's an example processor for those who would like to use one.
/// <summary> /// Registers additional types that cannot be directly seen from Web API, like SignalR messages. /// </summary> public sealed class AddAdditionalTypeProcessor<T>: IDocumentProcessor where T : class { public void Process(DocumentProcessorContext context) { context.SchemaResolver.AddSchema(typeof(T), isIntegerEnumeration: false, JsonSchema.FromType<T>()); } }
And usage:
services.AddSwaggerDocument(settings => { settings.DocumentProcessors.Add(new AddAdditionalTypeProcessor<MyTypeToExport>()); });
This example does have problems with nested types. Solution was to change the implementation to the following:
public sealed class AddAdditionalTypeProcessor<T> : IDocumentProcessor where T : class
{
public void Process(DocumentProcessorContext context)
{
context.SchemaGenerator.Generate(typeof(T).ToContextualType(), context.SchemaResolver);
}
}
What @lahma suggested has problems
it generates yaml with non-compliant (openapi:3.0.0) parts like type: null it causes the generated code from this yaml to have wrong types (instead of actual type it uses object type instead for the properties). It also causes some classes to be duplicated by adding 2 to the classname like Customer and Customer2.
@FerdinandBrunauer s suggestion works allright.
@FerdinandBrunauer example worked for me as a workaround for the issue I was having. When using [FromForm] my model wasn't being generated in the Swagger Schema section. I'm not sure if there is something I missed but I used the above code to just add the model/type manually. I would prefer not to though so if anyone else has a solution or could let me know what I missed, it would be much appreciated.
I'm using NSwag in my ASP.NET Core project (
app.UseOpenApi()
).Is it possible to add additional models, which are not used in any controller action, to the generated api descriptions?