【问题标题】:unable to update existing json list using jsonconverter无法使用 jsonconverter 更新现有的 json 列表
【发布时间】:2017-08-21 11:30:31
【问题描述】:

我试图在 json 中添加字段,同时反序列化来自服务器的响应,然后将其存储到数据库中

这里是响应的模型

 public class Response : RealmObject
    {

        [JsonConverter(typeof(QuotationConverter))]
        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public IList<Quotation> quotationsList { get; }

        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public IList<Order> ordersList { get; }
    }

QuotationConverter 代码,我从另一个 json 获取客户名称并将其存储到报价中

 protected override IList<Quotation> parseArray(Type objectType, JArray jsonArray)
        {

            try
            {
                Realm realm = Realm.GetInstance();
                foreach (JObject data in jsonArray)
                {

                    String customerId = data.GetValue("customerId").ToString();
                    Customer customer = realm.All<Customer>().Where(c => c.customerId == Java.Lang.Long.ParseLong(customerId)).FirstOrDefault();
                    if (customer != null)
                    {
                        String customerName = customer.customerName;
                        data.Add("customerName", customerName);
                    }

                }

                realm.Dispose();
                var quotationsList = jsonArray.ToObject<IList<Quotation>>();

                List<Quotation> quotation = new List<Quotation>(quotationsList);

                return quotationsList;
            }
            catch(Exception e)
            {

                Debug.WriteLine(" exception "+e.StackTrace);
            }

            return null;
        }

        protected override Quotation parseObject(Type objectType, JObject jsonObject)
        {
            throw new NotImplementedException();
        }
    }

这里是 JsonConverter

 public abstract class JsonConverter<T> : Newtonsoft.Json.JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return (objectType == typeof(JsonConverter<T>));

        }

        protected abstract T parseObject(Type objectType, JObject jsonObject);

        protected abstract IList<T> parseArray(Type objectType, JArray jsonArray);
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {

            try
            {              
               var jsonArray = JArray.Load(reader);
               var data=  parseArray(objectType, jsonArray);              
               return data;

            }
            catch(Exception e)
            {
                Debug.WriteLine(e.StackTrace);
            }
            return null;

        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {

            Debug.WriteLine("Mo " + value);


        }
    }

the issue is when i am getting Response object inside that quotationsList is coming blank.

从服务器接收到的 JSON

quotationsList: [
  {
    "account": null,
    "contactId": 0,
    "currency": "USD",
    "customerId": 5637144583,
    "deliveryAddress": "19TH and Edwardsville RD (RT203)\nGranite City,IL62040\nUSA",
    "expiryDate": "2017-09-04",
    "followUpDate": "2017-09-01",
    "mQuotationId": null,
    "opportunityId": 0,
    "postedOn": null,
    "prospectId": 0,
    "quotationFor": null,
    "quotationId": 5637155076,
    "quotationName": "United States Steel",
    "quotationNumber": "UST1-000022",
    "quotationStatus": "Confirmed",
    "requestReceiptDate": "2017-08-05",
    "requestShipDate": "2017-08-05",
    "siteId": "GLEN1",
    "wareHouseId": "37"
  }

预期的 json

quotationsList: [
  {
    "account": null,
    "contactId": 0,
    "currency": "USD",
    "customerId": 5637144583,
    "deliveryAddress": "19TH and Edwardsville RD (RT203)\nGranite City,IL62040\nUSA",
    "expiryDate": "2017-09-04",
    "followUpDate": "2017-09-01",
    "mQuotationId": null,
    "opportunityId": 0,
    "postedOn": null,
    "prospectId": 0,
    "quotationFor": null,
    "quotationId": 5637155076,
    "quotationName": "United States Steel",
    "quotationNumber": "UST1-000022",
    "quotationStatus": "Confirmed",
    "requestReceiptDate": "2017-08-05",
    "requestShipDate": "2017-08-05",
    "siteId": "GLEN1",
    "wareHouseId": "37",
    "customerName":"Jhon Caro"
  }

报价模型

 public class Quotation : RealmObject , IMaster, IMedia, IProduct
    {
        [PrimaryKey]
        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public String mQuotationId { get; set; } = Guid.NewGuid().ToString();

        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public long quotationId { get; set; }

        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public String customerName { get; set; }

        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public string quotationName { get; set; }

        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public string quotationNumber{ get; set; }

        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public string deliveryAddress { get; set; }

        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public string expiryDate { get; set; }

        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public string requestShipDate { get; set; }

        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public string requestReceiptDate { get; set; }

        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public long prospectId { get; set; }

        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public string followUpDate { get; set; }

        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public long opportunityId { get; set; }

        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public string postedOn { get; set; }



    }

更新

protected override IList<Quotation> parseArray(Type objectType, JArray jsonArray)
{

    try
    {
        Realm realm = Realm.GetInstance();
        var data = jsonArray.ToObject<IList<Quotation>>();
        List<Quotation> quotationList = new List<Quotation>(data);



        foreach (Quotation quotation in quotationList)
        {

            long customerId = quotation.customerId;
            Customer customer = realm.All<Customer>().Where(c => c.customerId == customerId).FirstOrDefault();
            if (customer != null)
            {
                String customerName = customer.customerName;
                quotation.customerName = customerName;
            }

        }

        realm.Dispose();


        return quotationList;
    }
    catch(Exception e)
    {

        Debug.WriteLine(" exception "+e.StackTrace);
    }

    return null;
}

这就是我的反序列化被调用的方式

响应 responseData = await Task.Run(() => JsonConvert.DeserializeObject(content));

【问题讨论】:

  • 区别在于最后一个字段customerName,我将其添加为一个新字段
  • 你能告诉我们为什么你按照你的方式编写代码,而不是仅仅在List&lt;Quotation&gt; quotation = new List&lt;Quotation&gt;(quotationsList);这行List&lt;Quotation&gt; quotation = new List&lt;Quotation&gt;(quotationsList);之后设置customerName属性吗?
  • quotationsList 有这么多记录,我正在为quotationsList 中存在的所有列表项添加customerName,所以一旦我准备好引文列表,我就会创建一个新列表并将其发回跨度>
  • 当然,我明白了。但是您将 JSON 转换为jsonArray,摆弄jsonArray,然后将其转换为List&lt;Quotation&gt;。您是否尝试过将 JSON 转换为 jsonArray,将其转换为 List&lt;Quotation&gt;,然后改用 List&lt;Quotation&gt;
  • 不让我试试

标签: c# json.net realm


【解决方案1】:

这里的问题不是 JSON 反序列化或添加到 json 数组,而是您没有来自数据库的记录的问题。

你正在使用这个:

 long customerId = quotation.customerId;
            Customer customer = realm.All<Customer>().Where(c => c.customerId == customerId).FirstOrDefault();
            if (customer != null)
            {
                String customerName = customer.customerName;
                quotation.customerName = customerName;
            }

FirstOrDefault 期望查询返回零个或多个项目,但您只想访问代码中的第一个项目(即您不确定是否存在具有给定键的项目)

将此更改为First(); 并查看它是否抛出异常,如果是,那么这是您的问题和您的:

realm.All<Customer>().Where(c => c.customerId == customerId)

正在返回不正确的数据。

【讨论】:

  • 我只是在修改一个字段,即报价单中的客户名称,如果客户名称存在,我会将其分配给报价单的客户名称,否则它将保持原样。因此,客户表中没有必要存在每个客户 ID,因此我首先使用或使用默认值,当客户名称不存在时,它会将报价单的客户名称设为 null,我看不出代码有任何问题。我尝试了你的 First 并且它生成异常,因为客户 ID 不存在于客户中,但正如我所说的那样没有必要
  • 问题是当你确实有一个返回值时会发生什么。
  • 我也试过你的First,但同样的问题。当ReadJson返回数据时,接收数据的变量总是空白
  • 尝试将列表序列化为 JSON:JsonConvert.SerializeObject(quotationsList, Formatting.None)
  • 我试图通过将 parseArray 的返回类型更改为字符串来将其写入QuotationConverter ,但仍然无法正常工作
【解决方案2】:
public class Response : RealmObject
{
    //JsonConverter attribute should be decorating 'Quotation' class
    //[JsonConverter(typeof(QuotationConverter))]
    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
    public IList<Quotation> quotationsList { get; }

    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
    public IList<Order> ordersList { get; }
}

【讨论】:

  • 你的意思是说而不是IList&lt;Quotation&gt; 我应该只使用Quotation 吗?
  • 不,我的意思是把你的 JsonConverter 属性移到 Quotation 类
【解决方案3】:

我认为您的转换器的这种方法不正确

public override bool CanConvert(Type objectType)
{
    return (objectType == typeof(JsonConverter<T>));
}

objectType 在这种情况下是IList&lt;Quotation&gt; 类型而不是JsonConverter&lt;IList&lt;Quotation&gt;&gt;。我相信这应该是:

public override bool CanConvert(Type objectType)
{
    return (objectType == typeof(T));
}

编辑:虽然我确实认为这是不正确的,但我不再相信这是问题的根本原因。我已经准确地重现了这个问题,解决方法是改变这一行。

public IList<Quotation> quotationsList { get; }

public IList<Quotation> quotationsList { get; set; }

JsonConvert 需要一个公共 setter 才能为属性赋值。

我也改了这一行

Response responseData = await Task.Run(() => JsonConvert.DeserializeObject(content));

Response responseData = await Task.Run(() => JsonConvert.DeserializeObject<Response>(content));

这告诉 DeserializeObject 调用尝试反序列化到哪个类。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-01
    • 2021-05-14
    • 1970-01-01
    相关资源
    最近更新 更多