-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SchemaId already used for different type #1607
Comments
Fixed by using
From issue #1431: #1431 (comment) |
@domaindrivendev Not sure who the repo owner is but judging by the likes I'm not the only one with this issue. maybe it could get looked into? |
By default, SB uses the short (unqualified name) which has its benefits because it keeps the docs simpler but also it’s downside if model names are duplicated in different namespaces. In this case, you can provide a custom naming strategy as described above. That’s it! Not sure what else needs to be “looked into”. Are expecting SB to do something else out of the box? If so, please elaborate on proposed behavior? |
Instead of a 'global' setting using something like:
notice the |
if you don't want to expose fullname of your model then
|
To get a slightly nicer type name I came up with this: public class SwashbuckleSchemaHelper
{
private readonly Dictionary<string, int> _schemaNameRepetition = new();
// borrowed from https://github.com/domaindrivendev/Swashbuckle.AspNetCore/blob/95cb4d370e08e54eb04cf14e7e6388ca974a686e/src/Swashbuckle.AspNetCore.SwaggerGen/SchemaGenerator/SchemaGeneratorOptions.cs#L44
private string DefaultSchemaIdSelector(Type modelType)
{
if (!modelType.IsConstructedGenericType) return modelType.Name.Replace("[]", "Array");
var prefix = modelType.GetGenericArguments()
.Select(genericArg => DefaultSchemaIdSelector(genericArg))
.Aggregate((previous, current) => previous + current);
return prefix + modelType.Name.Split('`').First();
}
public string GetSchemaId(Type modelType)
{
string id = DefaultSchemaIdSelector(modelType);
if (!_schemaNameRepetition.ContainsKey(id))
_schemaNameRepetition.Add(id, 0);
int count = _schemaNameRepetition[id] + 1;
_schemaNameRepetition[id] = count;
return $"{id}{(count > 1 ? count.ToString() : "")}";
}
} Usage looks like this: services.AddSwaggerGen(options =>
{
var schemaHelper = new SwashbuckleSchemaHelper();
options.CustomSchemaIds(type => schemaHelper.GetSchemaId(type));
}); More details here: https://blog.johnnyreilly.com/2022/08/31/swashbuckle-schemaid-already-used |
In my case, the issue was triggered by a couple of nested types with the same name, but their parents were completely different. So, services.AddSwaggerGen(options =>
{
options.CustomSchemaIds(type => string.Join('.', new[] { type.ReflectedType?.Name, type.Name }.Where(x => x != null)));
}); worked fine for me |
Swashbuckle.AspNetCore should be able to re-use the same schema id for the same types, even if they're nested in different classes, right? I could not find another open issue for that scenario, so I think a new issue should be created. |
@johnnyreilly had a good idea, but I found that it kept incrementing the count with each view of the swagger page or file, so I made a bit of a tweak to it to make it able to be repeatably called:
` |
I see it - have updated my blogpost and credited you @GlennPiper: https://blog.johnnyreilly.com/2022/08/31/swashbuckle-schemaid-already-used |
also running into this, why would |
the same here ;) happy to found this discussion. In my case the Id can be made unique by adding last part of namespace, but what I have realized we do not need to copy&paste any source code from SB. It is actually available to us. So ultimate solution for my use-case is this var defaultSchemaIdSelector = swaggerGenOptions.SchemaGeneratorOptions.SchemaIdSelector;
swaggerGenOptions.CustomSchemaIds(modelType => {
var defaultId = defaultSchemaIdSelector(modelType);
var prefix = modelType.Namespace?.Split(".").Last();
return String.IsNullOrEmpty(prefix) ? defaultId : String.Concat(prefix, ".", defaultId);
}); I really love the idea of keeping list of types with collisions and use the index to make the Id unique. Just have you considered to store in the list the @swashbuckle to me it looks like great idea to have this automatic number-based decoration as a part of the library. Not inside the |
I'm getting this error because I think that for some reason it conflicts with a class that I have called
Module
. Changing the name of that class is not an option, so is there a way to fix this? Maybe the best question is; why does this error even occur at all?Can't use schemaId "$Module" for type "$System.Reflection.Module". The same schemaId is already used for type "$Prjct.Data.Models.Module"
Swashbuckle.AspNetCore.Swagger version 5.2.1
Stacktrace:
The text was updated successfully, but these errors were encountered: