How to pass none english letters to Json

265 Views Asked by At

I'm working on a Xamarin Forms app for Android & iOS

I'm trying to figure out how to pass none english letters to Json file.

My language is Swedish and whenever I use characters like (Å, Ä, Ö) the app crashes.

So how do I fix this please ?

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

drawer.json

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

There are 3 best solutions below

3
Dominik Viererbe On

The json parser crashes, because the json data is not encoded correctly. The special caracters (ä, ö, å) have to be encoded with the same \u syntax.

Using this should work:

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

Out of curiosity I found another Solution: https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-character-encoding using the 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); 
        }
    }
}

Make it work with Xamarin/netstandard2.0/netstandard2.1

IMPORTANT: To make this work in a Xamarin Project to have to reference the System.Text.Json Nuget Package. (https://www.nuget.org/packages/System.Text.Json).

You can do this with the .NET CLI (Command Line Interface):

dotnet add package System.Text.Json

The Reason for this is that the System.Text.Json API's were first shipped with .NET Core 3 (https://devblogs.microsoft.com/dotnet/try-the-new-system-text-json-apis/) and are therefore not included in the netstandard2.0 or netstandard2.1 framework, which existed before .NET Core 3.

How can I see that I am targeting netstandard2.0 or netstandard2.1?

When you look into the .csproj File you should see a line like this:

<TargetFramework>netstandard2.0</TargetFramework>

or

<TargetFramework>netstandard2.1</TargetFramework>

If <TargetFramework> contains another value you most likely don't have to add the System.Text.Json Nuget Package.

0
Adrain On

Use JsonConvert instead,I test it on my side and it works fine. The code is from the sample I create under this question:Write a Text File (or PDF File) from Json in Xamarin.forms

code like:

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