Windows Phone,如何反序列化嵌套了Array的json

时间:2012-03-30 00:02:57

标签: json windows-phone-7 nested json.net datacontractjsonserializer

我现在正在做一个Windows Phone项目,需要向Web服务请求一些json数据。 如果json结构是这样的     [Dictionary1,      Dictionary2,      Dictionary3     ] 那么,DataContractJsonSerializer工作正常。 但是下一个请求我将得到一个复杂的json数据,它不起作用。喜欢     [       [Dictionary1]       [Dictionary2]       [Dictionary3]     ]

真实数据是:

    [

        [{"length":5734.042,"duration":1680,"legs":
            [
                {"length":685,"duration":555.42,"type":"walk","locs":

                    [

                        {"coord":{"x":2546445,"y":6675512},"arrTime":"201203290959","depTime":"201203290959","name":null},
                        {"coord":{"x":2546433.8,"y":6675498.3},"arrTime":"201203291000","depTime":"201203291000","name":"Teekkaripolku"}
                    ]
                },


                {"length":4158,"duration":420,"type":"5","code":"2506  2","locs":
                    [
                        {"coord":{"x":2546168,"y":6674959},"arrTime":"201203291009","depTime":"201203291009","name":"Alvar Aallon puisto","code":"2222235","shortCode":"E2226","stopAddress":"Otaniementie"},
                        {"coord":{"x":2546337,"y":6674857},"arrTime":"201203291009","depTime":"201203291009","name":"Dipoli","code":"2222204","shortCode":"E2204","stopAddress":"Otaniementie"}
                    ]
                }
            ]
        }],


        [{"length":5734.042,"duration":1680,"legs":
            [
                {"length":685,"duration":555.42,"type":"1", "code":"1111", "locs":
                    [
                        {"coord":{"x":2546445,"y":6675512},"arrTime":"201203290952","depTime":"201203290952","name":null},
                        {"coord":{"x":2546433.8,"y":6675498.3},"arrTime":"201203290953","depTime":"201203290953","name":"Teekkaripolku"}
                    ]
                },
                {"length":4158,"duration":420,"type":"5","code":"2194  2","locs":
                    [   {"coord":{"x":2546168,"y":6674959},"arrTime":"201203291002","depTime":"201203291002","name":"Alvar Aallon puisto","code":"2222235","shortCode":"E2226","stopAddress":"Otaniementie"},
                        {"coord":{"x":2546337,"y":6674857},"arrTime":"201203291002","depTime":"201203291002","name":"Dipoli","code":"2222204","shortCode":"E2204","stopAddress":"Otaniementie"}
                    ]
                }
            ]
        }]

    ]

,班级模型是:

[DataContract]
public class RouteList
{
    [DataMember]
    public List<Route> oneRoute;

}

---
    [DataContract]
public class Route
{
    [DataMember(Name = "length", IsRequired = true)]
    public Double length { get; set; }

    [DataMember(Name = "duration", IsRequired = true)]
    public Double duration { get; set; }

   [DataMember(Name = "legs", IsRequired = true)] 
    public List<Leg> legs { get; set; }
}

----
    [DataContract] 
public class Leg
{
    [DataMember(Name = "length", IsRequired = true)]
    public Double length { get; set; }

    [DataMember(Name = "duration", IsRequired = true)]
    public Double duration { get; set; }

    [DataMember(Name = "type", IsRequired = true)]
    public String type { get; set; }

    [DataMember(Name = "code", IsRequired = false)]
    public String code { get; set; }

    [DataMember(Name = "locs", IsRequired = true)]
    public List<Loc> locs { get; set; }

    [DataMember(Name = "shape", IsRequired = false)]
    public String shape { get; set; }
}

-----

    [DataContract] 
public class Loc
{
    [DataMember(Name = "coord", IsRequired = true)]
    public String coord { get; set; }

    [DataMember(Name = "arrTime", IsRequired = true)]
    public String arrTime { get; set; }

    [DataMember(Name = "depTime", IsRequired = true)]
    public String depTime { get; set; }

    [DataMember(Name = "name", IsRequired = true)]
    public String name { get; set; }

    [DataMember(Name = "code", IsRequired = false)]
    public String code { get; set; }

    [DataMember(Name = "shortCode", IsRequired = false)]
    public String shortCode { get; set; }

    [DataMember(Name = "stopAddress", IsRequired = false)]
    public String stopAddress { get; set; }

}

和反序列化代码:

 System.IO.MemoryStream mStream = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(e.Result));
 DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(List<RouteList>));
 result = (List<RouteList>)serializer.ReadObject(mStream);

我尝试过DataContractJsonSerializer和json.NET。但失败了。最可能的问题是嵌套数组,模型:RouteList。有谁知道如何解决它?非常感谢。

2 个答案:

答案 0 :(得分:1)

问题可能是因为您的类创建,在结束检查之前,您处理解析结果的模型类。或者,如果您需要帮助,请添加更多信息,例如模型类的结构,用于解析json等的代码。这里似乎没有任何内容。 Json.Net将做所有的技巧,你需要采取的唯一努力是正确建立你的类类型.. 享受编码

答案 1 :(得分:1)

在Olli Saarikivi的帮助下,问题得以解决。 在他允许的情况下,在这里发布他的解决方案,万一其他人可能需要它。

// The request response handler

var routeResults = new List<CompoundRoute>();

if (e.Result.Trim().Length != 0)
{
  JArray json = JArray.Parse(e.Result);

  foreach (var token in json)
 {
    var routeArray = token as JArray;
    if (routeArray != null)
    {
        var compoundRoute = new CompoundRoute { Routes = new Route[routeArray.Count] };
        for (int i = 0; i < compoundRoute.Routes.Length; ++i)
        {
            compoundRoute.Routes[i] = new Route(routeArray[i]);
        }
        routeResults.Add(compoundRoute);
    }
 }
}

 // The data model

 [DataContract]
 public class CompoundRoute
 {
    private static readonly Route[] EmptyRoutes = new Route[0];

    public CompoundRoute()
    {
        Routes = EmptyRoutes;
    }

    [DataMember]
    public Route[] Routes;
 }

[DataContract]
public class Route
{
   public Route(JToken token)
   {
    Length = token.Value<double>("length");

    int durationSeconds = token.Value<int>("duration");
    Duration = TimeSpan.FromSeconds(durationSeconds);

    JArray legTokens = token["legs"] as JArray;
    if (legTokens != null)
    {
        Legs = new Leg[legTokens.Count];
        for (int i = 0; i < Legs.Length; ++i)
        {
            Legs[i] = new Leg(legTokens[i]);
        }
    }
  }

  [DataMember]
  public double Length;
  [DataMember]
  public TimeSpan Duration;
  [DataMember]
  public Leg[] Legs;
}

[DataContract]
public class Leg
{
  public Leg(JToken token)
  {
    Length = token.Value<double>("length");

    double durationSeconds = token.Value<double>("duration");
    Duration = TimeSpan.FromSeconds((int)Math.Round(durationSeconds));

    Type = token.Value<string>("type");

    string lineCode = token.Value<string>("code");
    if (lineCode != null)
    {
        Line = App.Cache.GetOrCreate(lineCode, () => new Line(lineCode));
    }

    if (Type == "12") // Commuter trains
    {
        Line.ShortName = Utils.RemoveLeadingNumbers(Line.ShortName);
    }

    JArray locTokens = token["locs"] as JArray;
    if (locTokens != null)
    {
        Locs = new LegLocation[locTokens.Count];
        for (int i = 0; i < Locs.Length; ++i)
        {
            Locs[i] = new LegLocation(locTokens[i]);
        }
    }
    else
    {
        Locs = new LegLocation[0];
    }

    JArray shapeTokens = token["shape"] as JArray;
    if (shapeTokens != null)
    {
        Shape = new ReittiCoordinate[shapeTokens.Count];
        for (int i = 0; i < Shape.Length; ++i)
        {
            var shapeToken = shapeTokens[i];
            double x = shapeToken.Value<double>("x");
            double y = shapeToken.Value<double>("y");
            var coordinate = new ReittiCoordinate(y, x);
            Shape[i] = coordinate;
        }
    }
}

[DataMember]
public double Length;
[DataMember]
public TimeSpan Duration;
[DataMember]
public string Type;
[DataMember]
public Line Line;
[DataMember]
public LegLocation[] Locs;
[DataMember]
public ReittiCoordinate[] Shape;
}

[DataContract]
public class LegLocation
{
  public LegLocation(JToken token)
  {
    var coordToken = token["coord"];
    double x = coordToken.Value<double>("x");
    double y = coordToken.Value<double>("y");
    Coord = new ReittiCoordinate(y, x);

    string arrTimeString = token.Value<string>("arrTime");
    ArrTime = DateTime.ParseExact(arrTimeString, "yyyyMMddHHmm", null);

    string depTimeString = token.Value<string>("depTime");
    DepTime = DateTime.ParseExact(depTimeString, "yyyyMMddHHmm", null);

    Name = token.Value<string>("name");
 }

 [DataMember]
 public ReittiCoordinate Coord;
 [DataMember]
 public DateTime ArrTime;
 [DataMember]
 public DateTime DepTime;
 [DataMember]
 public string Name;
}