Repository navigation
Labels
WIPpriority:p2Medium. Generally has a work-around and a smaller sub-set of customers is affected. SLA <=30 daysMedium. Generally has a work-around and a smaller sub-set of customers is affected. SLA <=30 daystype:bugA broken experienceA broken experience
Milestone
Description
Relative reference in subdirectory OpenApi document fails to load
When loading a document which is splitted into multiple documents relative references are failing to load when a parent document is in a subdirectory.
What happens is, that a System.IO.FileNotFoundException is thrown:
Could not find file '<path to root of document structure>\Pets.json'.
StackTrace:
at Microsoft.Win32.SafeHandles.SafeFileHandle.CreateFile(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options)
at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
at System.IO.Strategies.OSFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
at System.IO.Strategies.FileStreamHelpers.ChooseStrategyCore(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
at System.IO.File.OpenRead(String path)
at Microsoft.OpenApi.Readers.Services.DefaultStreamLoader.<LoadAsync>d__4.MoveNext() in C:\Users\user\source\repos\OpenAPI.NET\src\Microsoft.OpenApi.Readers\Services\DefaultStreamLoader.cs:line 47
at Microsoft.OpenApi.Readers.Services.OpenApiWorkspaceLoader.<LoadAsync>d__4.MoveNext() in C:\Users\user\source\repos\OpenAPI.NET\src\Microsoft.OpenApi.Readers\Services\OpenApiWorkspaceLoader.cs:line 46
at Microsoft.OpenApi.Readers.OpenApiYamlDocumentReader.<ReadAsync>d__3.MoveNext() in C:\Users\user\source\repos\OpenAPI.NET\src\Microsoft.OpenApi.Readers\OpenApiYamlDocumentReader.cs:line 105
at Microsoft.OpenApi.Readers.OpenApiTextReaderReader.<ReadAsync>d__3.MoveNext() in C:\Users\user\source\repos\OpenAPI.NET\src\Microsoft.OpenApi.Readers\OpenApiTextReaderReader.cs:line 83
at Microsoft.OpenApi.Readers.OpenApiStreamReader.<ReadAsync>d__3.MoveNext() in C:\Users\user\source\repos\OpenAPI.NET\src\Microsoft.OpenApi.Readers\OpenApiStreamReader.cs:line 71
at Microsoft.OpenApi.Readers.Services.OpenApiWorkspaceLoader.<LoadAsync>d__4.MoveNext() in C:\Users\user\source\repos\OpenAPI.NET\src\Microsoft.OpenApi.Readers\Services\OpenApiWorkspaceLoader.cs:line 47
at Microsoft.OpenApi.Readers.OpenApiYamlDocumentReader.<ReadAsync>d__3.MoveNext() in C:\Users\user\source\repos\OpenAPI.NET\src\Microsoft.OpenApi.Readers\OpenApiYamlDocumentReader.cs:line 105
at Microsoft.OpenApi.Readers.OpenApiTextReaderReader.<ReadAsync>d__3.MoveNext() in C:\Users\user\source\repos\OpenAPI.NET\src\Microsoft.OpenApi.Readers\OpenApiTextReaderReader.cs:line 83
at Microsoft.OpenApi.Readers.OpenApiStreamReader.<ReadAsync>d__3.MoveNext() in C:\Users\user\source\repos\OpenAPI.NET\src\Microsoft.OpenApi.Readers\OpenApiStreamReader.cs:line 71
at Program.<<Main>$>d__0.MoveNext() in C:\Users\user\source\repos\OpenApiReferencesInSubDirectories\OpenApiReferencesInSubDirectories\Program.cs:line 17
Files to reproduce
OpenApi.NET Version: 1.6.14
using Microsoft.OpenApi.Readers;
OpenApiStreamReader openApiStreamReader = new OpenApiStreamReader(new OpenApiReaderSettings
{
BaseUrl = new Uri("<path to root of document structure>"),
ReferenceResolution = ReferenceResolutionSetting.ResolveLocalReferences,
LoadExternalRefs = true,
});
FileStream fileStream = new FileStream("Root.json", FileMode.Open, FileAccess.Read);
var document = await openApiStreamReader.ReadAsync(fileStream);./Root.json
{
"openapi": "3.0.0",
"info": {
"version": "1.0.0",
"title": "Swagger Petstore",
"license": {
"name": "MIT"
}
},
"servers": [
{
"url": "http://petstore.swagger.io/v1"
}
],
"paths": {
"/pets": {
"get": {
"summary": "List all pets",
"operationId": "listPets",
"responses": {
"200": {
"description": "An array of pets",
"content": {
"application/json": {
"schema": {
"$ref": "./Directory/AllPets.json#/components/schemas/AllPets"
}
}
}
}
}
}
}
}
}./Directory/AllPets.json
{
"openapi": "3.0.0",
"info": {
"version": "1.0.0",
"title": "Swagger Petstore"
},
"paths": {
},
"components": {
"schemas": {
"AllPets": {
"$ref": "./Pets.json#/components/schemas/Pets"
}
}
}
}./Directory/Pets.json
{
"openapi": "3.0.0",
"info": {
"version": "1.0.0",
"title": "Swagger Petstore"
},
"paths": {
},
"components": {
"schemas": {
"Pets": {
"type": "array",
"items": {
"$ref": "./Pet.json#/components/schemas/Pet"
}
},
"Pet": {
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"name": {
"type": "string"
},
"tag": {
"type": "string"
}
}
}
}
}
}Metadata
Metadata
Assignees
Labels
WIPpriority:p2Medium. Generally has a work-around and a smaller sub-set of customers is affected. SLA <=30 daysMedium. Generally has a work-around and a smaller sub-set of customers is affected. SLA <=30 daystype:bugA broken experienceA broken experience
Activity
baywet commentedon Feb 7, 2025
closing since #2133 was merged
dldl-cmd commentedon Feb 13, 2025
Vincent Biret (@baywet) The issue is still present. As the parameter
LoadExternalRefsis set totrue. If the parameter is set tofalse, the issue would be solved by the PR #2133 as it only fixed that the reference could be parsed correctly.With the current main branch, the following exception is thrown:
This exception occurs because the Uri is build from
OpenApiReaderSettings.BaseUrland appends the relative path. This construction happens inOpenApiModelFactoryin the methodLoadExternalRefsAsync.My expectation would be that the
baseUrlis the location of the current document. This would allow to use relative references to the current file instead of the settings base url.I wanted to start implementing a fix also for this issue, but I would like to get some understanding of the expected behavior with a few classes:
OpenApiDocument.BaseUribe the location of the current document orhttps://openapi.net/<guid>?OpenApiModelFactory.LoadExternalRefsAsyncreuse the existingOpenApiWorkspaceas all documents should be loaded into one workspace?ResolveReferenceon theOpenApiDocumentonly on theOpenApiWorkspace?baywet commentedon Feb 13, 2025
dldl-cmd which version of the library are you testing with?
dldl-cmd commentedon Feb 13, 2025
Vincent Biret (@baywet) v2 - I tested with latest main branch (c4bdccc)
baywet commentedon Feb 13, 2025
Thanks for confirming!
Since you're already setup to test this and build locally, Is this something you'd like to submit a pull request for provided some guidance?
dldl-cmd commentedon Feb 13, 2025
Vincent Biret (@baywet) Yes, I would like to do a PR on this issue. I already look at some code pieces therefore I came up with the above questions.
baywet commentedon Feb 13, 2025
To answer your questions:
Let us know if you have any additional comments or questions.
dldl-cmd commentedon Feb 13, 2025
OpenApiReferenceor theOpenApiDocumentto turn the relative reference inside of a document to an absolute reference, which could then be given toOpenApiWorkspace.ResolveReference(<absolute path>).With the
OpenApiReference.HostDocumentproperty it should be possible on a reference itself.baywet commentedon Feb 13, 2025
I think it'd make sense, feel free to startup a PR, seeing the code will make things a bit more concrete at this point.
darrelmiller commentedon Feb 19, 2025
Relative references should be resolved in any implementation of IStreamLoader, not in an OpenAPIDocument.
Fix: relative references in subdirectory documents are not loading mi…
Fix: relative references in subdirectory documents are not loading mi…
Fix: relative references in subdirectory documents are not loading mi…
fix: relative references in subdirectory documents are not loading #1674