将新项目添加到自定义类

时间:2017-06-14 10:19:20

标签: c# json wpf reflection

我有一组用于将JSON反序列化的类。我的程序将定期查找对此JSON文件的更改,如果找到任何更改,将使用反射将新数据推送到这些类的属性。

我需要在成功更新后找到添加到Item2类(SocialExportJSON.SocialExportData.Item2)集合中的任何新项目。

我的JSON类看起来像这样(还有更多,但我想避免太大的代码墙):

public class Item2 : INotifyPropertyChanged
{
    [JsonProperty("type")]
    private string type;

    public string Type
    {
        get
        {
            return type;
        }
        set
        {
            if (type != value)
            {
                type = value;
                RaisePropertyChanged("Type");
            }
        }
    }

    [JsonProperty("id")]
    private string id;

    public string ID
    {
        get
        {
            return id;
        }
        set
        {
            if (id != value)
            {
                id = value;
                RaisePropertyChanged("ID");
            }
        }
    }

    [JsonProperty("postedIso8601")]
    private string postedIso8601;

    public string PostedIso8601
    {
        get
        {
            return postedIso8601;
        }
        set
        {
            if (postedIso8601 != value)
            {
                postedIso8601 = value;
                RaisePropertyChanged("PostedIso8601");
            }
        }
    }

    [JsonProperty("postedTimestamp")]
    private object postedTimestamp;

    public object PostedTimestamp
    {
        get
        {
            return postedTimestamp;
        }
        set
        {
            if (postedTimestamp != value)
            {
                postedTimestamp = value;
                RaisePropertyChanged("PostedTimestamp");
            }
        }
    }

    [JsonProperty("engagement")]
    private Engagement engagement;

    public Engagement Engagement
    {
        get
        {
            return engagement;
        }
        set
        {
            if (engagement != value)
            {
                engagement = value;
                RaisePropertyChanged("Engagement");
            }
        }
    }

    [JsonProperty("source")]
    private Source2 source;

    public Source2 Source
    {
        get
        {
            return source;
        }
        set
        {
            if (source != value)
            {
                source = value;
                RaisePropertyChanged("Source");
            }
        }
    }

    [JsonProperty("author")]
    private Author author;

    public Author Author
    {
        get
        {
            return author;
        }
        set
        {
            if (author != value)
            {
                author = value;
                RaisePropertyChanged("Author");
            }
        }
    }

    [JsonProperty("content")]
    private Content content;

    public Content Content
    {
        get
        {
            return content;
        }
        set
        {
            if (content != value)
            {
                content = value;
                RaisePropertyChanged("Content");
            }
        }
    }

    [JsonProperty("location")]
    private Location location;

    public Location Location
    {
        get
        {
            return location;
        }
        set
        {
            if (location != value)
            {
                location = value;
                RaisePropertyChanged("Location");
            }
        }
    }

    [JsonProperty("publication")]
    private Publication publication;

    public Publication Publication
    {
        get
        {
            return publication;
        }
        set
        {
            if (publication != value)
            {
                publication = value;
                RaisePropertyChanged("Publication");
            }
        }
    }

    [JsonProperty("metadata")]
    private Metadata metadata;

    public Metadata Metadata
    {
        get
        {
            return metadata;
        }
        set
        {
            if (metadata != value)
            {
                metadata = value;
                RaisePropertyChanged("Metadata");
            }
        }
    }

    //Event handling
    public event PropertyChangedEventHandler PropertyChanged;

    private void RaisePropertyChanged(string property)
    {
        //Console.WriteLine("Updated");
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
    }
}

public class SocialExportData : INotifyPropertyChanged
{
    [JsonProperty("dataType")]
    private string dataType;

    public string DataType
    {
        get
        {
            return dataType;
        }
        set
        {
            if (dataType != value)
            {
                dataType = value;
                RaisePropertyChanged("DataType");
            }
        }
    }

    [JsonProperty("id")]
    private int id;

    public int ID
    {
        get
        {
            return id;
        }
        set
        {
            if (id != value)
            {
                id = value;
                RaisePropertyChanged("ID");
            }
        }
    }

    [JsonProperty("story")]
    private Story story;

    public Story Story
    {
        get
        {
            return story;
        }
        set
        {
            if (story != value)
            {
                story = value;
                RaisePropertyChanged("Story");
            }
        }
    }

    [JsonProperty("order")]
    private string order;

    public string Order
    {
        get
        {
            return order;
        }
        set
        {
            if (order != value)
            {
                order = value;
                RaisePropertyChanged("Order");
            }
        }
    }

    [JsonProperty("lifetime")]
    private string lifetime;

    public string Lifetime
    {
        get
        {
            return lifetime;
        }
        set
        {
            if (lifetime != value)
            {
                lifetime = value;
                RaisePropertyChanged("Lifetime");
            }
        }
    }

    [JsonProperty("maxAge")]
    private int maxAge;

    public int MaxAge
    {
        get
        {
            return maxAge;
        }
        set
        {
            if (maxAge != value)
            {
                maxAge = value;
                RaisePropertyChanged("MaxAge");
            }
        }
    }

    [JsonProperty("maxSize")]
    private int maxSize;

    public int MaxSize
    {
        get
        {
            return maxSize;
        }
        set
        {
            if (maxSize != value)
            {
                maxSize = value;
                RaisePropertyChanged("MaxSize");
            }
        }
    }

    [JsonProperty("consumeCount")]
    private int consumeCount;

    public int ConsumeCount
    {
        get
        {
            return consumeCount;
        }
        set
        {
            if (consumeCount != value)
            {
                consumeCount = value;
                RaisePropertyChanged("ConsumeCount");
            }
        }
    }

    [JsonProperty("consumeInterval")]
    private int consumeInterval;

    public int ConsumeInterval
    {
        get
        {
            return consumeInterval;
        }
        set
        {
            if (consumeInterval != value)
            {
                consumeInterval = value;
                RaisePropertyChanged("ConsumeInterval");
            }
        }
    }

    [JsonProperty("items")]
    private ObservableCollection<Item2> items;

    public ObservableCollection<Item2> Items
    {
        get
        {
            return items;
        }
        set
        {
            if (items != value)
            {
                items = value;
                RaisePropertyChanged("Items");
            }
        }
    }

    //Event handling
    public event PropertyChangedEventHandler PropertyChanged;

    private void RaisePropertyChanged(string property)
    {
        //Console.WriteLine("Updated");
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
    }
}

public class SocialExportJSON : INotifyPropertyChanged
{
    [JsonProperty("id")]
    private string id;

    public string ID
    {
        get
        {
            return id;
        }
        set
        {
            if (id != value)
            {
                id = value;
                RaisePropertyChanged("ID");
            }
        }
    }

    [JsonProperty("ttl")]
    private int ttl;

    public int TTL
    {
        get
        {
            return ttl;
        }
        set
        {
            if (ttl != value)
            {
                ttl = value;
                RaisePropertyChanged("TTL");
            }
        }
    }

    [JsonProperty("serial")]
    private long serial;

    public long Serial
    {
        get
        {
            return serial;
        }
        set
        {
            if (serial != value)
            {
                serial = value;
                RaisePropertyChanged("Serial");
            }
        }
    }

    [JsonProperty("formatType")]
    private string formatType;

    public string FormatType
    {
        get
        {
            return formatType;
        }
        set
        {
            if (formatType != value)
            {
                formatType = value;
                RaisePropertyChanged("FormatType");
            }
        }
    }

    [JsonProperty("modifiedIso8601")]
    private string modifiedIso8601;

    public string ModifiedIso8601
    {
        get
        {
            return modifiedIso8601;
        }
        set
        {
            if (modifiedIso8601 != value)
            {
                modifiedIso8601 = value;
                RaisePropertyChanged("ModifiedIso8601");
            }
        }
    }

    [JsonProperty("modifiedTimestamp")]
    private long modifiedTimestamp;

    public long ModifiedTimestamp
    {
        get
        {
            return modifiedTimestamp;
        }
        set
        {
            if (modifiedTimestamp != value)
            {
                modifiedTimestamp = value;
                RaisePropertyChanged("ModifiedTimestamp");
            }
        }
    }

    [JsonProperty("timezone")]
    private string timezone;

    public string Timezone
    {
        get
        {
            return timezone;
        }
        set
        {
            if (timezone != value)
            {
                timezone = value;
                RaisePropertyChanged("Timezone");
            }
        }
    }

    [JsonProperty("dataType")]
    private string dataType;

    public string DataType
    {
        get
        {
            return dataType;
        }
        set
        {
            if (dataType != value)
            {
                dataType = value;
                RaisePropertyChanged("DataType");
            }
        }
    }

    [JsonProperty("exports")]
    private ObservableCollection<SocialExportData> exports;

    public ObservableCollection<SocialExportData> Exports
    {
        get
        {
            return exports;
        }
        set
        {
            if (exports != value)
            {
                exports = value;
                RaisePropertyChanged("Exports");
            }
        }
    }

    //Event handling
    public event PropertyChangedEventHandler PropertyChanged;

    private void RaisePropertyChanged(string property)
    {
        //Console.WriteLine("Updated");
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
    }
}

在另一个类中,我有一个方法可以反序列化为我的JSON类的全局实例。它看起来像这样:

    public SocialExportJSON socialExportData;

    private async void DownloadAndDeserializeJSONAsync()
    {
        try
        {
            //Create a web client with the supplied credentials
            var exportClient = new WebClient { Credentials = new NetworkCredential(uName, pw), Encoding = Encoding.UTF8};

            //Create a task to download the JSON string and wait for it to finish
            var downloadTask = Task.Run(() => exportClient.DownloadString(new Uri(eURL)));
            downloadTask.Wait();

            //Get the string from the task
            var JSONString = await downloadTask;

            //Create a task to deserialize the JSON from the last task
            var DeserializeTask = Task.Run(() => JsonConvert.DeserializeObject<SocialExportJSON>(JSONString));
            DeserializeTask.Wait();

            SocialExportJSON sej = await DeserializeTask;

            //Check the timestamp first to see if we should change the data
            if(socialExportData == null)
            {
                //Get the data from the task
                socialExportData = await DeserializeTask;
            }
            else if(sej.ModifiedTimestamp != socialExportData.ModifiedTimestamp)
            {
                //Get the data from the task
                SocialExportJSON newData = await DeserializeTask;
                GetNewItems(newData);
                SetNewData(newData);

                //Call the exportUpdated event when the task has finished
                exportUpdated();
            }
        }
        catch (Exception e)
        {
            MessageBox.Show(e.Message.ToString());
        }
    }

在我的SetNewData函数中,如下所示,我使用反射来设置全局类的属性。因为我设置整个集合而不是遍历每个类中的每个属性,所以我无法使用CollectionChanged事件来查找新项目。

    public void SetNewData(SocialExportJSON newData)
    {
        //Loop through each of the properties and copy from source to target
        foreach (PropertyInfo pi in socialExportData.GetType().GetProperties())
        {
            if (pi.CanWrite)
            {
                pi.SetValue(socialExportData, pi.GetValue(newData, null), null);
            }
        }
    }

有没有办法可以修改我的SetNewData函数,使其调用CollectionChanged?如果没有,那么在我的Item2集合中添加任何新增内容的最佳方法是什么?

1 个答案:

答案 0 :(得分:1)

  

在我的主要功能中。我创建了一个名为SocialExport的类的实例,如下所示:

&
  

这个类是包含我的JSON类的全局实例的地方,我的事件处理程序是这样添加的

SocialExport s = new SocialExport("http://example.json", "example", "example");. 

然后,您正在为 s.socialExportData.Exports[0].Items.CollectionChanged += CollectionChanged; 的特定实例CollectionChanged事件连接一个事件处理程序。

如果你创建一个新的ObservableCollection<Item2>,你显然必须将一个事件处理程序连接到这个。将新项目添加到新实例时,将不会调用与旧对象关联的事件处理程序。

因此,无论何时使用反序列化创建新的ObservableCollection<Item2>,您都应该连接一个新的事件处理程序。

您可以在ObservableCollection<Item2>方法中执行此操作。另一个选项是只创建一个集合实例,并从中删除和添加项目。