【问题标题】:BSON Object Being Partially DeserializedBSON 对象被部分反序列化
【发布时间】:2014-10-25 03:48:08
【问题描述】:

我正在尝试将来自 Web API 调用的 BSON HTTP 响应消息反序列化为自定义类型。

 using (HttpClient client = new HttpClient())
        {
            client.BaseAddress = new Uri("http://localhost:1234");

            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/bson"));
            HttpResponseMessage result;

            result = await client.GetAsync("/endpoint/");

            MediaTypeFormatter[] formatters = new MediaTypeFormatter[] {
                new BsonMediaTypeFormatter()
            };

            if (result.IsSuccessStatusCode)
            {
                try
                {
                    RootObject res = await result.Content.ReadAsAsync<RootObject>(formatters);
                }
                catch (Exception e)
                {

                }
            }

我知道 Web API 正在返回 BSON,我通过 Fiddler 进行了检查,上面的代码实际上确实正确地反序列化了 RootObject 中的大多数内容。似乎所有派生类都没有被反序列化,只是作为空值输入到对象中。这是未反序列化的派生类的示例。

RootObject.Events.Teams.Linescores

根对象

[DataContract(Namespace = "", Name = "RootObject")]
[Serializable] 
public class  RootObject: infoBase
{
    [DataMember(EmitDefaultValue = false, Order = 30)]
    [JsonProperty(NullValueHandling = NullValueHandling.Ignore, Order = 30)]
    public IEnumerable<eventInfo> events { get; set; }

    public RootObject() { }
}

事件对象

[DataContract(Namespace = "", Name = "event")]
[Serializable]
[KnownType(typeof(subEventTeam))]
public class eventInfo : infoBase
{
    [DataMember(EmitDefaultValue = false, Order = 170)]
    [JsonProperty(NullValueHandling = NullValueHandling.Ignore, Order = 170)]
    public List<eventTeamBase> teams { get; set; }

    public eventInfo() { }
}

团队基础和特定团队类型

[DataContract(Namespace = "", Name = "team")]
[Serializable]
[KnownType(typeof(bbLinescoreInfo))]
public class eventTeamBase : infoBase {

     [DataMember(Order = 20)]
     [JsonProperty(Order = 20)]
     public string location { get; set; }

     [DataMember(Order = 30, EmitDefaultValue = false)]
     [JsonProperty(Order = 30, NullValueHandling = NullValueHandling.Ignore)]
     public string nickname { get; set; }

     [DataMember(EmitDefaultValue = false, Name = "linescores", Order = 130)]
     [JsonProperty(NullValueHandling = NullValueHandling.Ignore, Order = 130)]
     public IEnumerable<linescoreBase> linescores { get; set; }

  public eventTeamBase() { }
}

[DataContract(Namespace = "", Name = "team")]
[Serializable]
public class  subEventTeam : eventTeamBase
{
   public subEventTeam () { }
}

Linescore 基础和特定对象

[DataContract(Name = "linescores", Namespace = "")]
[Serializable]
[KnownType(typeof(subLinescoreInfo))]
public class linescoreBase : infoBase
{
    public bool isProcessing = false;
    public int teamId { get; set; }

    public linescoreBase() { }
}
[DataContract(Name = "linescores", Namespace = "")]
[Serializable] public class  subLinescoreInfo : linescoreBase
{
    [DataMember]
    public int inning { get; set; }
    [DataMember]
    public int? score { get; set; }

    public subLinescoreInfo() { };
}

这是响应的反序列化(然后重新序列化)部分,无法输出到 JSON。

{
"status":"OK",
"recordCount":1,
"RootObject":[
{
  "events":[
  {
      "teams":[
      {
         "location":"Tallahassee",
         "nickname":"Razors",
         "linescores":[
            {},{},{},{},{},{},{},{}]
       }
   }
 }

}

如您所见,它正确地填写了一些信息(还有很多,我已经大幅削减只是为了说明问题)。但是线分数返回空值。如前所述,数据返回正确且不为空。

我觉得我对已知类型做错了,我尝试了许多将它们放在不同位置的组合,结果没有改变。任何帮助将不胜感激。

【问题讨论】:

    标签: json deserialization bson


    【解决方案1】:

    经过大量搜索和尝试错误的事情后,我在另一个线程中找到了类似的解决方案。 JSON Solution

    我通过做几乎完全相同的事情解决了这个问题,但使用的是 BSON 而不是 JSON。

    这是我需要在 Web API 的全局配置文件中添加的代码

    BsonMediaTypeFormatter bsonFormatter = new BsonMediaTypeFormatter();
    bsonFormatter.SerializerSettings.TypeNameHandling = TypeNameHandling.Objects;
    bsonFormatter.AddQueryStringMapping("accept", "bson", "application/bson");
    GlobalConfiguration.Configuration.Formatters.Add(bsonFormatter);
    

    这段代码进入了客户端。

    BsonMediaTypeFormatter bsonFormatter = new BsonMediaTypeFormatter();
    bsonFormatter.SerializerSettings.TypeNameHandling = TypeNameHandling.Objects;
    MediaTypeFormatter[] formatters = new MediaTypeFormatter[] {
       bsonFormatter
    };
    

    其他一切都保持不变,并且被反序列化而没有发生任何事件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-02
      • 1970-01-01
      • 2021-01-19
      • 1970-01-01
      • 2017-08-15
      • 2021-12-08
      • 1970-01-01
      相关资源
      最近更新 更多