【问题标题】:How to pass none english letters to Json如何不将英文字母传递给Json
【发布时间】:2021-12-18 00:47:22
【问题描述】:

我正在开发适用于 Android 和 iOS 的 Xamarin Forms 应用

我正在尝试弄清楚如何将无英文字母传递给 Json 文件。

我的语言是瑞典语,每当我使用(Å、Ä、Ö)等字符时,应用程序就会崩溃。

请问我该如何解决这个问题?

DrawerViewModel.cs

class DrawerViewModel : BaseViewModel {
     ...

     public static DrawerViewModel BindingContext => 
        drawerViewModel = PopulateData<DrawerViewModel>("drawer.json");

     ...

     private static T PopulateData<T>(string fileName)
    {
        var file = "CykelStaden.Data." + fileName;

        var assembly = typeof(App).GetTypeInfo().Assembly;

        T data;

        using (var stream = assembly.GetManifestResourceStream(file))
        {
            var serializer = new DataContractJsonSerializer(typeof(T));
            data = (T)serializer.ReadObject(stream);
        }

        return data;
    }
     
}

抽屉.json

{
    "itemList": [
     {
         "itemIcon": "\ue729",
         "itemName": "Länd"
      },
      {
          "itemIcon": "\ue72c",
          "itemName": "Höjd"
      },
      {
          "itemIcon": "\ue733",
          "itemName": "Mått"
      },
      {
          "itemIcon": "\ue72b",
          "itemName": "Inställningar"
      }
  ]
}

【问题讨论】:

  • 它是如何崩溃的?你能产生一个minimal reproducible example 吗?如果一切都是unicode,你应该没问题。检查您的编码。
  • 输入文件使用什么编码?
  • 哪一行导致崩溃?有什么例外?你使用什么编码?您是否尝试过使用 Newtonsoft 而不是 Microsoft 序列化程序?
  • 你说的是文件名还是文件内容?如果是后者,请确保使用 UTF-8 编码保存文件。
  • 我已经添加了drawer.json文件,但我其实不知道如何检查我的应用程序的编码。

标签: c# json xml xamarin datacontractjsonserializer


【解决方案1】:

json 解析器崩溃,因为 json 数据未正确编码。特殊字符(äöå)必须使用相同的\u 语法进行编码。

使用它应该可以工作:

{
  "itemList": [
    {
      "itemIcon": "\uE729",
      "itemName": "L\u00E4nd"
    },
    {
      "itemIcon": "\uE72C",
      "itemName": "H\u00F6jd"
    },
    {
      "itemIcon": "\uE733",
      "itemName": "M\u00E5tt"
    },
    {
      "itemIcon": "\uE72B",
      "itemName": "Inst\u00E4llningar"
    }
  ]
}

【讨论】:

  • 你是怎么知道如何改变这些特殊字符的?
  • 我来自德国,所以我知道问题所在。我为自己编写了一个简单的控制台应用程序来转换数据,但您可以在任何 unicode 表中查找值。它是用前导零填充到长度 4 的字符的十六进制值。
【解决方案2】:

改用 JsonConvert,我自己测试它,它工作正常。 代码来自我在这个问题下创建的示例:Write a Text File (or PDF File) from Json in Xamarin.forms

代码如下:

 private void saveload_clicked(object sender, EventArgs e)
{
    string myfile=Path.Combine(FileSystem.AppDataDirectory,"myjson.txt");
    var obj = JsonConvert.DeserializeObject(File.ReadAllText(myfile));
}

【讨论】:

    【解决方案3】:

    出于好奇,我找到了另一个解决方案:https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-character-encoding 使用 JsonSerializer

    public class DrawerItem
    {
        [JsonPropertyName("itemIcon")]
        public string Icon { get; set; }
    
        [JsonPropertyName("itemName")]
        public string Name { get; set; }
    }
    
    public class DrawerItemList
    {
        private static readonly JsonSerializerOptions _serializerOptions = new JsonSerializerOptions
        {
            // This Encoder allows to parse Unicode Symbols without \uXXXX escaping
            Encoder = JavaScriptEncoder.Create(UnicodeRanges.All)
        };
    
        [JsonPropertyName("itemList")]
        public IEnumerable<DrawerItem> DrawerItems { get; set; }
    
        public static DrawerItemList LoadFromEmbeddedJsonFile(CancellationToken cancellationToken = default)
        {
            return LoadFromEmbeddedJsonFileAsync(cancellationToken).Result;
        }
    
        public static async Task<DrawerItemList> LoadFromEmbeddedJsonFileAsync(CancellationToken cancellationToken = default)
        {
            const string ManifestResourceName = "CykelStaden.Data.drawer.json";
    
            var assembly = Assembly.GetExecutingAssembly();
    
            using (var stream = assembly.GetManifestResourceStream(ManifestResourceName))
            {
                return await JsonSerializer.DeserializeAsync<DrawerItemList>(stream, _serializerOptions, cancellationToken); 
            }
        }
    }
    

    使其适用于 Xamarin/netstandard2.0/netstandard2.1

    重要提示:要在 Xamarin 项目中进行这项工作,必须引用 System.Text.Json Nuget 包。 (https://www.nuget.org/packages/System.Text.Json)。

    您可以使用 .NET CLI(命令行界面)执行此操作:

    dotnet add package System.Text.Json
    

    原因是 System.Text.Json API 最初是随 .NET Core 3 (https://devblogs.microsoft.com/dotnet/try-the-new-system-text-json-apis/) 一起提供的,因此不包含在 .NET Core 3 之前存在的 netstandard2.0netstandard2.1 框架中.

    我怎样才能看到我的目标是netstandard2.0netstandard2.1

    当您查看 .csproj 文件时,您应该会看到如下一行:

    <TargetFramework>netstandard2.0</TargetFramework>
    

    <TargetFramework>netstandard2.1</TargetFramework>
    

    如果&lt;TargetFramework&gt; 包含另一个值,您很可能不必添加System.Text.Json Nuget 包。

    【讨论】:

    • 让这段代码正常工作
    • 可能是因为我使用 .net5 作为目标框架:/
    • 我想我也在用那个
    • 错误信息是什么?
    • 代码几乎在每一行都给了我红色的下划线。添加导入也无济于事
    猜你喜欢
    • 2020-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-16
    • 2013-07-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多