1

私は現在、Windows Phone プロジェクトを行っており、Web サービスに json データを要求する必要があります。json 構造が [Dictionary1, Dictionary2, Dictionary3] のような場合、DataContractJsonSerializer は正常に動作します。しかし、次のリクエストで複雑なjsonデータが取得されますが、機能しません。[[辞書1]、[辞書2]、[辞書3]]のように

実際のデータは次のとおりです。

    [

        [{"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 を試しました。しかし失敗しました。最も考えられる問題は、ネストされた配列、model:RouteList です。誰もそれを修正する方法を知っていますか? どうもありがとう。

4

2 に答える 2

1

問題はクラスの作成が原因である可能性があります。結論を出す前に、解析結果を処理するモデルクラスを確認してください。または、モデルクラスの構造、jsonの解析に使用したコードなど、さらに情報を追加するためのヘルプが必要な場合は、ここでは何も構成されていないようです。Json.Netはすべてのトリックを実行します。必要な作業は、クラスタイプを適切に構築することだけです。コーディングをお楽しみください

于 2012-03-30T13:28:49.307 に答える
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;
}
于 2012-04-02T16:57:11.447 に答える