$ref URI's are not escaped
Describe the bug
If type name contains a character that should be escaped, generated swagger json contains unescaped URI which causes swagger-client to fail resolving the reference.
To Reproduce
Create a OpenApiReference with Id that contains a + character (e.g. MyClass+MyNestedClass). Real-world scenario here is using Type.FullName on nested class, which uses + to concatenate the nested class name to base class name. Then try to use generated schema.
swagger-client then should fail to resolve JSON pointer, because it tries to unescape all URI tokens and will try to search for MyClass MyNestedClass instead of MyClass+MyNestedClass.
Expected behavior
$ref URI's are escaped when serializing.
Additional context
As seen at https://swagger.io/docs/specification/using-ref/ ,
The value of $ref uses the JSON Reference notation, and the portion starting with # uses the JSON Pointer notation
JSON Pointer RFC says that
A JSON Pointer can be represented in a URI fragment identifier by encoding it into octets using UTF-8 [RFC3629], while percent-encoding those characters not allowed by the fragment rule in [RFC3986].
it also says that it can be just a string
A JSON Pointer can be represented in a JSON string value. Per [RFC4627], Section 2.5, all instances of quotation mark '"' (%x22), reverse solidus '' (%x5C), and control (%x00-1F) characters MUST be escaped.
So ultimately, it's either swagger-client that works incorrectly or these refs should be actually escaped. But as it stands, swagger-client breaks if these characters are not escaped.
Component names are limited in the specification.
All the fixed fields declared above are objects that MUST use keys that match the regular expression: ^[a-zA-Z0-9.-_]+$.
https://spec.openapis.org/oas/latest.html#fixed-fields-5
Therefore there should be no need to do any escaping.
All the fixed fields declared above are objects that MUST use keys that match the regular expression: ^[a-zA-Z0-9.-_]+$.
So going by that requirement, then it shouldn't allow components with +?
E.g.
...
"components": {
"schemas": {
"MyNamespace.MyClass+MySubClass":
...
"myOtherPropertyInAnotherClass": {
"type": "array",
"items": {
"oneOf": [
{
"$ref": "#/components/schemas/MyNamespace.MyClass+MySubClass"
},
...
Should be invalid first because it contains schema object with key that does not match mentioned regex? But this does not seem to be enforced in any way either. Or is it on purpose not to do any strict spec validations?
So while technically it does seem redundant to not escape them, if spec is strictly followed, but if the spec is strictly followed, then wouldn't it also be correct to escape the ref's?
@Hoffs This validation rule is supposed to be checking the component names with the regex https://github.com/microsoft/OpenAPI.NET/blob/75bb4ef3fb7029b99152b6fd05bb678eaef40d06/src/Microsoft.OpenApi/Validations/Rules/OpenApiComponentsRules.cs#L20
I tested it and it does return an error in the diagnostics object.