Home > Software engineering >  File not found while parsing a json file in Xamarin Forms
File not found while parsing a json file in Xamarin Forms

Time:02-25

I have a problem in a Xamarin.Forms application that I am developing. I need to read the content of a .json file, to be showed in a CarouselView. I am using Newtonsoft.Json library to parse the file.

However, it continously gives to me an error that it cannot find the file. The c# code is as follows:

using System.Net.Http;
using System.Collections.ObjectModel;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using PalazzoVecchioDemo.Models;
using Newtonsoft.Json;
using System.IO;

namespace PalazzoVecchioDemo.Views
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class VisitChoice : ContentPage
    {
        private const string _json = "rooms.json";

        public ObservableCollection<Room> Rooms { get; set; } = new ObservableCollection<Room>();

        public VisitChoice()
        {
            InitializeComponent();

            //necessary to do data binding to elements present in this page
            //(in particular to the observable collection of rooms)
            BindingContext = this;
        }

        protected override void OnAppearing()
        {
            base.OnAppearing();

            string path = Directory.GetCurrentDirectory();
            string previousFolder = Path.Combine(path, @"..\");
            string jsonPath = Path.Combine(path, _json);

            var rooms = JsonConvert.DeserializeObject<Room[]>(File.ReadAllText(_json));

            Rooms.Clear();

            foreach(var room in rooms)
            {
                Rooms.Add(room);
            }
        }
    }
}

The .xaml code is as follows (I put only the significant part of it:

!-- Carousel view with all the contents -->
        <CarouselView Grid.Row="1" 
                      ItemsSource="{Binding Rooms}" 
                      Loop="False">
            <CarouselView.ItemTemplate>
                <DataTemplate>
                    <StackLayout>
                        <Frame HasShadow="True" 
                               BorderColor="DarkGray" 
                               CornerRadius="5" 
                               Margin="20" 
                               HeightRequest="300" 
                               HorizontalOptions="Center" 
                               VerticalOptions="CenterAndExpand">
                            <StackLayout>
                                <Label Text="{Binding Name}" 
                                       FontAttributes="Bold" 
                                       FontSize="Large" 
                                       HorizontalOptions="Center" 
                                       VerticalOptions="Center"
                                       AutomationProperties.IsInAccessibleTree="True"/>
                            </StackLayout>
                        </Frame>
                    </StackLayout>
                </DataTemplate>
            </CarouselView.ItemTemplate>
        </CarouselView>

The project structure is as follows; I am writing the VisitChoice page (inside the Views folder) and the file I want to read is rooms.json.

project structure

Anyone could please help me?

CodePudding user response:

I would suggest the following points:

  • in Visual Studio, it's possible to copy a file in the output folder. Please check the property windows when you click on the JSON file. Maybe it will not copy to the bin folder where your EXE or code is running.

  • Before you are starting with DeserializeObject, I would check the path if the file really exists. File. Exists() Method.

  • When you access the file, check if you are in the right folder. Maybe your file is in another subfolder, and you are one folder above.

  • For accessing, use total paths to avoid issues.

CodePudding user response:

It's best practice to avoid embed files in the way that you're doing. For JSON, I recommend you to create the file while your app is running, even if it will create just one time.

For that, you can:

  • Use, for example, App.xaml.cs to process your JSON (it will be one of the first classes to your project run). You can store your JSON (if it's static, seeing that you're trying to embed it) in a resx file to access the strings.

  • Creating and updating a JSON file:

        public void SaveJSON(string jsonText) 
        {
            File.WriteAllText(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "myJson.json"), jsonText);
        }
  • Get your JSON file to use it:
        public string GetJSON()
        {
            string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "myJson.json");
            string json = (File.Exists(path)) ? File.ReadAllText(path) : "";
            return json;
        }

If you don't want to create resx file, you can just, in your App.xaml.cs, pass for one time SaveJSON("") to create your JSON document.

  • Related