You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

解决JSON文件存在却触发FileNotFoundException的问题

Let's break down your problem and fix it step by step—you're hitting a common Xamarin pitfall with file paths, plus a couple of code details that need tweaking:

1. First: Fix Your Data Model (Critical Mistake)

You're using List<File> to deserialize your JSON, but System.IO.File is a built-in class for file operations, not a model for your place data. You need to create a custom class that matches your JSON structure (note the typo Adress/Address in your JSON—we'll handle that too):

using Newtonsoft.Json;

namespace Orbage
{
    public class Place
    {
        public string Label { get; set; }
        
        // Handle both "Adress" (typo) and "Address" from your JSON
        [JsonProperty("Address")]
        public string Address { get; set; }
        
        [JsonProperty("Adress")]
        public string AlternateAddress
        {
            set => Address = value; // Map the typo'd field to the correct property
        }
        
        public string Lat { get; set; }
        public string Lng { get; set; }
    }
}

Then update your deserialization line to use this class:

var places = JsonConvert.DeserializeObject<List<Place>>(json);

2. Fix the FileNotFoundException (Core Problem)

Xamarin doesn't use simple relative paths like "File.json"—you need to account for platform-specific file locations and resource settings. Here are the most common solutions:

Option A: Embed the JSON as a Project Resource

  • Setup: Right-click your DATA.json file in your shared/PCL project → Properties → Set Build Action to Embedded Resource.
  • Reading Code:
    var assembly = typeof(MapPage).GetTypeInfo().Assembly;
    // Replace "Orbage.DATA.json" with your project namespace + file path (e.g., if in a subfolder: "Orbage.Folder.DATA.json")
    using (Stream stream = assembly.GetManifestResourceStream("Orbage.DATA.json"))
    using (StreamReader reader = new StreamReader(stream))
    {
        var json = reader.ReadToEnd();
        var places = JsonConvert.DeserializeObject<List<Place>>(json);
        // Rest of your pin logic...
    }
    

Option B: Place the File in Platform-Specific Folders

For Android:

  • Setup: Move DATA.json to your Android project's Assets folder → Right-click → Properties → Set Build Action to AndroidAsset.
  • Reading Code:
    using (StreamReader reader = new StreamReader(Android.App.Application.Context.Assets.Open("DATA.json")))
    {
        var json = reader.ReadToEnd();
        var places = JsonConvert.DeserializeObject<List<Place>>(json);
        // Rest of your pin logic...
    }
    

For iOS:

  • Setup: Move DATA.json to your iOS project's Resources folder → Right-click → Properties → Set Build Action to BundleResource.
  • Reading Code:
    var filePath = Path.Combine(NSBundle.MainBundle.BundlePath, "DATA.json");
    var json = File.ReadAllText(filePath);
    var places = JsonConvert.DeserializeObject<List<Place>>(json);
    // Rest of your pin logic...
    }
    

3. Fix Pin & Map Logic Issues

Your current loop overwrites CustomPins every iteration and moves the map multiple times—fix that:

public MapPage()
{
    CustomMap customMap = new CustomMap { MapType = MapType.Street };
    
    // Initialize the CustomPins list once
    customMap.CustomPins = new List<CustomPin>();
    
    // ... (add your file reading/deserialization code here)
    
    foreach (var place in places)
    {
        if (double.TryParse(place.Lat, out double lat) && double.TryParse(place.Lng, out double lng))
        {
            CustomPin pin = new CustomPin
            {
                Type = PinType.Place,
                Position = new Position(lat, lng),
                Label = place.Label,
                Address = place.Address,
                Name = "Xamarin",
                Url = "http://xamarin.com/about/"
            };
            
            customMap.CustomPins.Add(pin);
            customMap.Pins.Add(pin);
        }
    }
    
    // Move the map once after adding all pins
    customMap.MoveToRegion(MapSpan.FromCenterAndRadius(new Position(37.79752, -122.40183), Distance.FromMiles(1.0)));
    
    Content = customMap;
}
  • Added double.TryParse to avoid crashes if Lat/Lng values are invalid
  • Moved Content = customMap to the end (optional but cleaner)
  • Fixed CustomPins to add pins instead of overwriting the list each time
  • Moved MoveToRegion outside the loop so it only runs once

内容的提问来源于stack exchange,提问作者ItsRaptorman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 18:23:14