【问题标题】:Json.NET preserving native typesJson.NET 保留本机类型
【发布时间】:2012-10-30 07:08:34
【问题描述】:

我使用 Json.NET (http://james.newtonking.com/projects/json/help/) 作为从服务器序列化和反序列化 JSON 的一种方式。假设我有以下 JSON 对象:

{
    "user" : {
         "name" : "Bob",
         "age" : 35
    },
    "location" : "California"
}

我能找到将其反序列化为本机类型的唯一方法是使用自定义 DTO,如下所示:

string jsonString = ""; // json string from above
Response result = JsonConvert.DeserializeObject<Response> (jsonString);

Response 类看起来像这样:

public class Response
{
    [JsonProperty("user")]
    public UserResponse User { get; set; }

    [JsonProperty("location")]
    public string Location { get; set; }
}

public class UserResponse
{
    [JsonProperty("name")]
    public string Name { get; set; }

    [JsonProperty("age")]
    public int Age { get; set; }
}

我想将其反序列化为本机类型,但我所处的环境并不总是知道 JSON 字符串的外观......所以当我不确切知道时很难使用自定义 DTO我在管什么。如果我没有将任何类传递给 JsonConvert.DeserializeObject(),那么我最终会得到 Json.NET 类型,而不是字符串、整数等原生类型。关于如何解决这个问题的任何建议?我应该改用其他 JSON 库吗?

谢谢!

【问题讨论】:

标签: c# .net json json.net


【解决方案1】:

这不会解决您所有的问题(这是不可能的),但这里有一个解决方案,可以让您使用有限的返回信息来解析 json。

在外层,您创建了一个名为 Vehicle 的对象。这包含汽车、船和飞机。您正在请求一些车辆,但您不知道它是汽车、船还是飞机(请注意,这可以很容易地扩展为处理一系列车辆或许多其他更复杂的响应)。在架构中,您有一些选项,例如;

"id": "vehicle.schema.json",
"type": "object",
"required": true,
"additionalProperties": false,
"properties": {
    "Car": {
        "type": "object",
        "required": false
        //other properties
    },
              "Boat": {
        "type": "object",
        "required": false
        //other properties
    },
            "Plane": {
        "type": "object",
        "required": false
        //other properties
    }

上面是您要添加到项目中的架构文件。如果您想拥有其中的几个,只需将更多元组添加到下面的 _schemaTypes 数组中。

   // code to set up your schema
  // Associate types to their JsonSchemas.  Order matters here.
  // After each parse, the schema is added to resolver, which is used in subsequent parses.
        _schemaTypes = new[]
        {
            Tuple.Create(typeof(Vehicle), "vehicle.schema.json"),
        }
        .ToDictionary(
            x => x.Item1,
            x => JsonSchema.Parse(
                File.ReadAllText(
                    Path.Combine(AppDomain.CurrentDomain.RelativeSearchPath ?? "",  @"Serialization\Schemas\") + x.Item2),
                    resolver));


 //method to return your deserialized object
 public T Deserialize<T>(IRestResponse response)
    {
        var schema = _schemaTypes[typeof(T)];

        T result = _serializer.Deserialize<T>(
                new JsonValidatingReader(
                    new JsonTextReader(
                        new StringReader(response.Content)))
                {
                    Schema = schema
                });
        return result;
    }

现在,在您解析响应后,您将拥有一个更通用的对象,您可以从那里编写一些代码来确定返回的更具体的对象是什么。我正在使用这种类型的方法来解析 json,其中它具有多个级别的嵌套对象和对象数组,并且相当有效。

【讨论】:

  • 您似乎创建了自己的问题并回答了它。还有一点就是OP用的是Json.Net,但是你用的是什么是未知的。
  • @L.B 这使用Newtonsoft.Json 和Newtonsoft.Json.Schema。我没有准确回答他的问题,因为该问题没有答案,我试图为解析 json 提供一些指导,信息有限。正如您在 OP 评论中所说,没有办法完全按照他的意愿行事。
  • @L.B 另外我不相信I don't always know what the JSON string will look like 这条线。我认为这是夸大其词,实际上意味着“根据服务器应用程序的当前状态,同一请求可以返回许多 json 变体。”如果是这种情况,那么一个好的架构可以处理所有这些变化。
  • +1 表示可行的模式,尽管没有所有需要的信息。
  • @Heather 谢谢。我应该添加什么使它更完整?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-31
相关资源
最近更新 更多