Json.NET保留原生类型

时间:2012-11-09 22:28:40

标签: c# .net json json.net

我正在使用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库吗?

谢谢!

1 个答案:

答案 0 :(得分:1)

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

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

"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,它有几层嵌套对象和对象数组,它非常有效。