3

ルートマイレージに関するデータを取得するために Web サービスを使用しています。次に、デシリアライザーを使用して解析しています。JSON は次のようになります。

[{"__type":"CalculateMilesReport:http:\/\/pcmiler.alk.com\/APIs\/v1.0","RouteID":null,"TMiles":445.5]

この応答には、いくつかの問題がありました。がコレクションにラップされるのはなぜですか? オブジェクト モデルを設定するにはどうすればよいですか? また、特別な __type 属性について不平を言っていました。だから、「ハック」して「準備」した文字列:

// Cut off first and last charachters [] - they send objects as arrays
rawJSON = rawJSON.Substring(1, rawJSON.Length - 2);

// Hide "__type" attribute as it messes up serializer with namespace
rawJSON = rawJSON.Replace("__type", "type");

その後、すべてがこのオブジェクトで機能しました:

[DataContract]
public class PCMilerResponse
{
    [DataMember(Name = "Errors", EmitDefaultValue = false)]
    public PCMilerError[] Errors { get; set; }

    [DataMember(Name = "TMiles", EmitDefaultValue = false)]
    public decimal DrivingDistance { get; set; }    
}

今、私はWebサービスへの呼び出しを変更し、次の応答を受け取りました

[
{"__type":"CalculateMilesReport:http:\/\/pcmiler.alk.com\/APIs\/v1.0","RouteID":null,"TMiles":445.5},
{"__type":"GeoTunnelReport:http:\/\/pcmiler.alk.com\/APIs\/v1.0","RouteID":null,"GeoTunnelPoints":
    [{"Lat":"34.730466","Lon":"-92.247147"},{"Lat":"34.704863","Lon":"-92.29329"},{"Lat":"34.676312","Lon":"-92.364654"},{"Lat":"29.664271","Lon":"-95.236735"}]
}
]

これで、配列と「__type」が存在する理由がわかりました。しかし、オブジェクトを適切に解析するためにオブジェクトを記述する方法がわかりません。特別な属性を適用する必要があり、おそらく汎用配列が必要だと思いますか? 適切に逆シリアル化する方法について何か助けはありますか?

PS私はさらにハッキングを行い、それらの文字列をオブジェクト内の2つのオブジェクトに置き換えることができますが、それを処理する「適切な」方法があるかどうか疑問に思います。

4

2 に答える 2

1

属性を非表示にすることについて__typeは、SO に関する議論があります。

これは、次の方法で解決したものです。

WebMethod の戻り値の型をオブジェクトに変更します。つまり、

[WebMethod]
public static object ApplyCredits(int addonid, int[] vehicleIds) 

それ以外の

[WebMethod]
public static WebMethodReturn ApplyCredits(int addonid, int[] veh

によって解決された別のもの

名前空間パラメーター[DataContract(Namespace = "")]をデータ コントラクトに追加します。

オブジェクトを適切に解析するための書き込み方法がわかりません

応答に基づいて、JSON が適合するクラスを構築できますが、モデル クラスがあるため、JSON が構築されたものと同じものを使用することになっています。たぶん、私はあなたの質問から何かを正しく得られませんでした。

以下は、JSON が適合するように細工されたモデルの例です。

public class ResultType
{
    public string RouteID { get; set; }
    public List<GeoTunnelPoints> Points { get; set; }
    public double TMiles { get; set; }

    public ResultType()
    {
        RouteID = "";
        Points = new List<GeoTunnelPoints>();
        TMiles = 0;
    }
}

public class GeoTunnelPoints
{
    double Lat { get; set; }
    double Lon { get; set; }

    public GeoTunnelPoints()
    {
        Lat = 0.0;
        Lon = 0.0;
    }
}

使用例:

// Your example JSON after excluding the __type
string input = 
                "[" +
                    "{" + 
                       "\"RouteID\":null, " +
                        "\"TMiles\":445.5}," +
                    "{" +
                        "\"RouteID\":null," +
                        "\"GeoTunnelPoints\":" +
                              "[" +
                                  "{\"Lat\":\"34.730466\",\"Lon\":\"-92.247147\"}," +
                                  "{\"Lat\":\"34.704863\",\"Lon\":\"-92.29329\"}," +
                                  "{\"Lat\":\"34.676312\",\"Lon\":\"-92.364654\"}," +
                                  "{\"Lat\":\"29.664271\",\"Lon\":\"-95.236735\"}" +
                              "]" +
                    "} " +
                "]";

List<ResultType> resultList = new List<ResultType>();
// This will be your C# result collection
resultList = new JavaScriptSerializer().Deserialize<List<ResultType>>(input);
于 2015-12-23T06:52:33.227 に答える