Как десериализовать документ Swagger с помощью $ref с помощью Json.NET?

Мне нужно десериализовать следующий Json:

{
    "swagger": "2.0",
    "info": {
        "version": "0.0.0",
        "title": "Simple API"
    },
    "paths": {
        "/": {
            "get": {
                "parameters": [
                    {
                        "$ref": "#/parameters/MyParameter"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "schema": {
                            "$ref": "#/definitions/MyDefinition"
                        }
                    }
                }
            }
        }
    },
    "parameters": {
        "MyParameter": {
            "name": "MyParameter",
            "in": "query",
            "type": "string"
        }
    },
    "definitions": {
        "MyDefinition": {
            "type": "string"
        }
    }
}

Это контракты, которые я определил с Json.NET

    public class SwaggerDocument
    {
        public IDictionary<string, Schema> definitions;
        public Info info;
        public IDictionary<string, Parameter> parameters;
        public IDictionary<string, PathItem> paths;
        public readonly string swagger;
        public Dictionary<string, object> vendorExtensions;
    }

    public class Schema
    {
        [JsonProperty("$ref", IsReference = true)]
        public string @ref;
        public string type;
    }

    public class Info
    {
        public string title;
        public Dictionary<string, object> vendorExtensions;
        public string version;
    }

    public class Parameter
    {
        public string name;
        public string @in;
        public string type;
        public Dictionary<string, object> vendorExtensions;
    }

    public class PathItem
    {
        public Operation get;
        public Dictionary<string, object> vendorExtensions;
    }

    public class Operation
    {
        public IList<Parameter> parameters;
        public IDictionary<string, Response> responses;
    }

    public class Response
    {
        public string description;
        public Schema schema;
    }

Я ожидаю, что следующее пройдет, но вместо этого параметр и определение будут нулевыми:

    [TestMethod]
    public void ShouldDeserializeReferences()
    {
        var swagger = JsonConvert.DeserializeObject<SwaggerDocument>(SwaggerWithRefs);
        var operation = swagger.paths.Values.First().get;
        var parameter = operation.parameters.First();
        var definition = operation.responses.First().Value.schema;
        Assert.AreEqual("MyParameter", parameter.name);
        Assert.AreEqual("string", definition.type);
    }

    private static readonly string SwaggerWithRefs = "{\r\n    \"swagger\": \"2.0\",\r\n    \"info\": {\r\n        \"version\": \"0.0.0\",\r\n        \"title\": \"Simple API\"\r\n    },\r\n    \"paths\": {\r\n        \"/\": {\r\n            \"get\": {\r\n                \"parameters\": [\r\n                    {\r\n                        \"$ref\": \"#/parameters/MyParameter\"\r\n                    }\r\n                ],\r\n                \"responses\": {\r\n                    \"200\": {\r\n                        \"description\": \"OK\",\r\n                        \"schema\": {\r\n                            \"$ref\": \"#/definitions/MyDefinition\"\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    },\r\n    \"parameters\": {\r\n        \"MyParameter\": {\r\n            \"name\": \"MyParameter\",\r\n            \"in\": \"query\",\r\n            \"type\": \"string\"\r\n        }\r\n    },\r\n    \"definitions\": {\r\n        \"MyDefinition\": {\r\n            \"type\": \"string\"\r\n        }\r\n    }\r\n}";

Можно ли определить контракты таким образом, чтобы сделать утверждения в тесте верными? Обратите внимание, что http://editor.swagger.io/ не имеет проблем с анализом этого json.

РЕДАКТИРОВАТЬ: ссылочный ответ упоминает только десериализацию как JObject. Есть ли способ получить такое же поведение с контрактами?

0 ответов

public class SwaggerDocument
{
    public string host { get; set; }
    public IDictionary<string, IDictionary<string, PathItem>> paths;
}

public class PathItem
{
    public string summary { get; set; }
    public string operationId { get; set; }
    public object parameters { get; set; }
    public object responses { get; set; }
}
Другие вопросы по тегам