1

これは非常に奇妙な問題であることがわかりました。xmlリクエストをWebAPIサービスに送信すると、すべてが正常に逆シリアル化されます。ただし、jsonリクエストを送信すると、このONEプロパティは逆シリアル化されません。オブジェクトは次のとおりです。

[Serializable]
[DataContract(Namespace = "")]
public class TransactionData
{
    // bunch of other properties that are unaffected ...

    private GeotagInfo _geotag;

    [DataMember(IsRequired = false, Name = "GeotagInfo", Order = 7)]
    public GeotagInfo GeotagInfo
    {
        get { return _geotag ?? new GeotagInfo(); }
        set { _geotag = value; }
    }
}


[DataContract(Namespace = "")]
public class GeotagInfo
{

    [DataMember(IsRequired = false, Name = "Longitude", Order = 1, EmitDefaultValue = false)]
    public string Longitude { get; set; }

    [DataMember(IsRequired = false, Name = "Latitude", Order = 2, EmitDefaultValue = false)]
    public string Latitude { get; set; }

    [Image(Nullable = true)]
    [DataMember(IsRequired = false, Name = "MapImage", Order = 3, EmitDefaultValue = false)]
    public string MapImage { get; set; }

    [XmlIgnore]
    public int TransactionId { get; set; }
}

xmlリクエストを使用してコントローラーのエントリポイントでブレークした場合。geotagプロパティがあり、完全に入力されています。jsonリクエストで同じことを行うと、geotagプロパティがインスタンス化されますが、その値はすべてnullです。この親オブジェクトの他のすべては問題ありません。

これは、jsonリクエストのプロパティです。

"GeotagInfo": {
  "Longitude": "-yy.yyyy",
  "Latitude": "xx.xxxx",
  "MapImage": "base64 string"
}

プロパティゲッターに注意してくださいget { return _geotag ?? new GeotagInfo(); }

xmlリクエストにはこれに関する問題はありません。しかし、それを削除して作成するとget { return _geotag; }、問題は解決します。残念ながら、これはサービスのより深いところに他の問題を引き起こします。

何が起きてる?xmlではうまく機能しますがjsonでは機能しません(デフォルトのゲッターを削除しない限り)。MVC4がjson.netを使用していることを知っているので、それはそれと関係があるかもしれません。

注:他のスレッドで提案されているように、クラスからシリアル化可能な属性を削除しようとしました。変化なし。

4

2 に答える 2

2

したがって、明らかに、Json.netシリアライザーの操作の順序には間違いなく違いがあります。パフォーマンスのために、ある種の怠惰な逆シリアル化を行おうとしているのではないかと思います。とにかく、私が書いたバグがあり、シリアライザーの違いが明らかになりました。

get { return _geotag ?? new GeotagInfo(); }

これにより、プライベートフィールドが設定されることはありません。そのはず:

get { return _geotag ?? (_geotag = new GeotagInfo()); }

したがって、プライベートフィールドは設定されていないというのが私の仮定です。これにより、本質的に遅延ロードの逆シリアル化が設定されているように感じます。デシリアライズプロセスを過ぎたので、プライベートフィールドで実行されているチェックは常にnullを返し、デフォルトで空のオブジェクトを返します。

于 2013-03-20T04:19:53.050 に答える
1

回避策は、2つのプロパティを作成することです。1つはシリアル化用で、もう1つはさらに使用するためのものです。

[Serializable]
[DataContract(Namespace = "")]
public class TransactionData
{
    // bunch of other properties that are unaffected ...

    private GeotagInfo _geotag;

    [DataMember(IsRequired = false, Name = "GeotagInfo", Order = 7)]
    public DataMember_GeotagInfo GeotagInfo
    {
        get;
        set;
    }

    public GeotagInfo GeotagInfo
    {
        get { return DataMember_GeotagInfo ?? new GeotagInfo(); }
        set { DataMember_GeotagInfo = value; }
    }
}
于 2013-02-27T20:20:55.987 に答える