在 Xamarin Forms 中解析 json 文件时找不到文件

File not found while parsing a json file in Xamarin Forms

我在开发的 Xamarin.Forms 应用程序中遇到问题。我需要读取 .json 文件的内容,显示在 CarouselView 中。我正在使用 Newtonsoft.Json 库来解析文件。

但是,它不断给我一个找不到文件的错误。 c#代码如下:

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);
            }
        }
    }
}

.xaml代码如下(我只放了重要的部分:

!-- 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>

项目结构如下;我正在编写 VisitChoice 页面(在 Views 文件夹内),我要读取的文件是 rooms.json.

谁能帮帮我?

我建议以下几点:

  • 在Visual Studio中,可以复制输出文件夹中的文件。点击JSON文件时请勾选属性windows。也许它不会复制到您的EXE或代码所在的bin文件夹中 运行.

  • 在开始使用 DeserializeObject 之前,我会检查路径是否确实存在该文件。文件。存在()方法。

  • 当您访问该文件时,请检查您是否在正确的文件夹中。可能你的文件在另一个子文件夹里,而你在上面一个文件夹。

  • 为了访问,使用总路径以避免问题。

最好避免以您正在执行的方式嵌入文件。对于 JSON,我建议您在应用 运行ning 时创建文件,即使它只会创建一次。

为此,您可以:

  • 例如,使用 App.xaml.cs 来处理您的 JSON(它将成为您项目 运行 的第一个 类) .您可以将 JSON(如果它是静态的,看到您正在尝试嵌入它)存储在 resx file 中以访问字符串。

  • 正在创建和更新 JSON 文件:

        public void SaveJSON(string jsonText) 
        {
            File.WriteAllText(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "myJson.json"), jsonText);
        }
  • 获取您的 JSON 文件以使用它:
        public string GetJSON()
        {
            string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "myJson.json");
            string json = (File.Exists(path)) ? File.ReadAllText(path) : "";
            return json;
        }

如果你不想创建resx file,你可以在你的App.xaml.cs中,通过一次SaveJSON("")来创建你的JSON文件。

当你在Xamarin.Forms项目中添加json文件作为Embedded resource时,你可以使用下面的代码读取和反序列化。

1.为 json 数据获取匹配的 类。

复制您的 json 字符串。单击编辑 > 选择性粘贴 > 粘贴 JSON 为 类。之后,你就可以得到你想要的类。

2。使用下面的代码读取 Embedded resourcejson 文件并反序列化。

 string _json = "rooms.json";
        Room ObjList = new Room();


        var assembly = typeof(Page20).GetTypeInfo().Assembly;
        Stream stream = assembly.GetManifestResourceStream($"{assembly.GetName().Name}.{_json}");
        using (var reader = new StreamReader(stream))
        {
            var jsonString = reader.ReadToEnd();

            ObjList = JsonConvert.DeserializeObject<Room>(jsonString);
        }