Сериализация и десериализация файла формата json в Avalonia MVVM

Возникла проблема с сериализацией и десериализацией файла json в avalonia. Имеется коллекция, и ее объекты необходимо сохранить в файл, и затем этот же файл открыть чтобы объекты появились на экране. Необходимо сделать через файловый менеджер. Также есть свойство не связанное с коллекцией, но в связи с ним меняется условие создания новых элементов коллекции, оно указано в комбобоксе.

View:

<StackPanel>
        <StackPanel Orientation="Horizontal">
            <ComboBox ItemsSource="{Binding Brand}" SelectedValue="{Binding CurrentBrand}"/>
            <Button Content="Add new row" Command="{Binding AddNewRow}"/>
            <Button Content="Save" Command="{Binding SaveFile}"/>
            <Button Content="Open file" Command="{Binding OpenFile}"/>
        </StackPanel>
        <ItemsControl ItemsSource="{Binding CarList}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal" VerticalAlignment="Center" Margin="10">
                        <TextBlock TextAlignment="Center" VerticalAlignment="Center" Width="50" Text="{Binding Id}"/>
                        <TextBox Text="{Binding Model}"/>
                    </StackPanel>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </StackPanel>

models:

 private int _id;
    private string _model;
public int Id
    {
        get => _id;
        set => this.RaiseAndSetIfChanged(ref _id, value);
    }
 public string Model
    {
        get => _model;
        set => this.RaiseAndSetIfChanged(ref _model, value);
    }

VM:

 public class MainWindowViewModel : ViewModelBase
    {
        private ObservableCollection<Car> _carList;
    
        public ObservableCollection<Car> CarList
        {
            get => _carList;
            set => this.RaiseAndSetIfChanged(ref _carList, value);
        }
    
        public ReactiveCommand<Unit, Unit> AddNewRow { get; set; }
        public ReactiveCommand<Unit, Unit> SaveFile { get; set; }
        public ReactiveCommand<Unit, Unit> OpenFile { get; set; }
    
        private string _currentBrand;
    
        public string CurrentBrand
        {
            get => _currentBrand;
            set
            {
                CarList.Clear();
                this.RaiseAndSetIfChanged(ref _currentBrand, value);
            }
        }
    
        public ObservableCollection<string> _brand;
    
        public ObservableCollection<string> Brand
        {
            get => _brand;
            set => this.RaiseAndSetIfChanged(ref _brand, value);
        }
    
    
        public MainWindowViewModel()
        {
            Brand = new ObservableCollection<string>();
            Brand.Add("BMW");
            Brand.Add("Audi");
            CarList = new ObservableCollection<Car>(new List<Car>());
    
            AddNewRow = ReactiveCommand.Create(() =>
            {
                if (CurrentBrand == Brand[0])
                {
                    CarList.Add(
                        new()
                        {
                            Id = CarList.Count + 1,
                            Model = "X5M",
                            
                        });
                }
                else if (CurrentBrand == Brand[1])
                {
                    CarList.Add(
                        new()
                        {
                            Id = CarList.Count + 1,
                            Model = "RS6",
                            
                        });
                }
                else
                {
                    CarList.Add(
                        new()
                        {
                            Id = CarList.Count + 1,
                            Model = "Не выбран бренд",
                            
                        });
                }
            });
            SaveFile = ReactiveCommand.Create(() =>
            {
                
        }
OpenFile = ReactiveCommand.Create(() =>
            {
                
        }

Ответы (1 шт):

Автор решения: Mikhail

Вот собственное решение, подскажите в чем проблема, на вскидку все работает.

MODELS:

public class Car: ViewModelBase
{
    private int _id;
    private string _model;
    private string _brand;

    [DataMember]
    public int Id
    {
        get => _id;
        set => this.RaiseAndSetIfChanged(ref _id, value);
    }

    [DataMember]
    public string Model
    {
        get => _model;
        set => this.RaiseAndSetIfChanged(ref _model, value);
    }
    [DataMember]
    public string Brand
    {
        get => _brand;
        set => this.RaiseAndSetIfChanged(ref _brand, value);
    }

VM:

public class MainWindowViewModel : ViewModelBase
{
    private ObservableCollection<Car> _carList;

    [XmlArray("Collection"), XmlArrayItem("Item")]
    public ObservableCollection<Car> CarList
    {
        get => _carList;
        set => this.RaiseAndSetIfChanged(ref _carList, value);
    }

    public ReactiveCommand<Unit, Unit> AddNewRow { get; set; }
    public ReactiveCommand<Unit, Unit> SaveFile { get; set; }
    public ReactiveCommand<Unit, Unit> OpenFile { get; set; }

    private string _currentBrand;

    public string CurrentBrand
    {
        get => _currentBrand;
        set
        {
            CarList.Clear();
            this.RaiseAndSetIfChanged(ref _currentBrand, value);
        }
    }

    public ObservableCollection<string> _brand;

    public ObservableCollection<string> Brand
    {
        get => _brand;
        set => this.RaiseAndSetIfChanged(ref _brand, value);
    }


    public MainWindowViewModel()
    {
        Brand = new ObservableCollection<string>();
        Brand.Add("BMW");
        Brand.Add("Audi");
        CarList = new ObservableCollection<Car>(new List<Car>());

        AddNewRow = ReactiveCommand.Create(() =>
        {
            if (CurrentBrand == Brand[0])
            {
                CarList.Add(
                    new()
                    {
                        Id = CarList.Count + 1,
                        Model = "X5M",
                        Brand = CurrentBrand
                    });
            }
            else if (CurrentBrand == Brand[1])
            {
                CarList.Add(
                    new()
                    {
                        Id = CarList.Count + 1,
                        Model = "RS6",
                        Brand = CurrentBrand
                    });
            }
            else
            {
                CarList.Add(
                    new()
                    {
                        Id = CarList.Count + 1,
                        Model = "Не выбран бренд",
                        Brand = null!
                    });
            }
        });
        SaveFile = ReactiveCommand.Create(() =>
        {
            // XmlSerializer xs = new XmlSerializer(typeof(ObservableCollection<Car>));
            // using (StreamWriter wr = new StreamWriter(@"C:\Users\Mikhail\Desktop\Cars.xml"))
            // {
            //     xs.Serialize(wr, CarList);
            // }
            SaveJsonFile();
        });
        OpenFile = ReactiveCommand.Create(OpenJsonFile);
    }
    string _path;
    private static FilePickerFileType Json { get; } = new("All xls")
    {
        Patterns = new[]
        {
            "*.elegir",
            "*.json"
        },
        MimeTypes = null,
        AppleUniformTypeIdentifiers = null,
    };
    private async void OpenJsonFile()
    {
        var topLevel = TopLevel.GetTopLevel(new MainWindow());
        var files = await topLevel.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
        {
            Title = "Open Json File",
            AllowMultiple = false,
            FileTypeFilter = new[] { Json },
            SuggestedStartLocation = await topLevel.StorageProvider.TryGetFolderFromPathAsync("C:\\")
        });
        if (files.Count >= 1)
        {
            // Open reading stream from the first file.
            await using var stream = await files[0].OpenReadAsync();
            using var streamReader = new StreamReader(stream);
            ObservableCollection<Car> deserialize = JsonConvert.DeserializeObject<ObservableCollection<Car>>(streamReader.ReadLine());
            CurrentBrand = deserialize[0].Brand;
            CarList = deserialize;
        }
    }

    private async void SaveJsonFile()
    {
        var topLevel = TopLevel.GetTopLevel(new MainWindow());
        var file = await topLevel.StorageProvider.SaveFilePickerAsync(new FilePickerSaveOptions
        {
            Title = "Save Json File",
            FileTypeChoices = new [] { Json },
            SuggestedStartLocation = await topLevel.StorageProvider.TryGetFolderFromPathAsync("C:\\"),
            SuggestedFileName = CurrentBrand + "-" + DateTime.Now.ToString("dd.MM.yyyy") + ".elegir",
            
        });
        if (file is not null)
        {
            // Open writing stream from the file.
            await using var stream = await file.OpenWriteAsync();
            using var streamWriter = new StreamWriter(stream);
            // Write some content to the file.
            string serialized = JsonConvert.SerializeObject(CarList);
            streamWriter.WriteLine(serialized);
        }
        // File.WriteAllText("SuperFile.json", JsonSerializer.Serialize(CarList));
    }
}

Json файл:

[{"Model":"X5M","Id":1,"Brand":"BMW"},{"Model":"X5M","Id":2,"Brand":"BMW"},{"Model":"X5M","Id":3,"Brand":"BMW"},{"Model":"X5M","Id":4,"Brand":"BMW"}]
→ Ссылка