しっぽを追いかけて

ぐるぐるしながら考えています

Unity と猫の話題が中心   掲載内容は個人の私見であり、所属組織の見解ではありません

Model からマルチバイト文字をエスケープして Json 文字列にシリアライズする

Xmlシリアライズばかり利用してたので、下記のように Json シリアライズで漢字などのマルチバイト文字を Unicode エスケープ(「\uXXXX」の表記)する記述法があると知りませんでした

{
  "title": "\u30BF\u30A4\u30C8\u30EB"
}

というわけで JSON.Net でマルチバイト文字をエスケープする設定方法を探してみました

まずは Model クラスの準備

下記のような感じでお手製の T4 テンプレートでプロパティに JsonProperty の属性をつけます

<#@ template debug="true" hostspecific="false" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".generated.cs" #>
//<auto-generated>
#region License
//-----------------------------------------------------------------------
// <copyright>
//     Copyright matatabi-ux 2014.
// </copyright>
//-----------------------------------------------------------------------
#endregion

namespace JsonSample.Models
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Xml.Serialization;
    using Newtonsoft.Json;

<# 
   Generate("Photo", new Property[] {
       new Property("uniqueId", "string", "ID", "[XmlAttribute(\"id\")]", "[JsonProperty(\"id\")]"),
       new Property("imageUri", "string", "画像Uri", "[XmlAttribute(\"image\")]", "[JsonProperty(\"image\")]"),
       new Property("title", "string", "タイトル", "[XmlAttribute(\"title\")]", "[JsonProperty(\"title\")]"),
       new Property("owner", "string", "撮影者", "[XmlAttribute(\"owner\")]", "[JsonProperty(\"owner\")]"),
   }, "Photo", "[XmlRoot(\"entity\")]");
#>
<#@ include file="../Templates/Model.ttinclude" #>
}

※ この T4 テンプレートは以前の投稿「Prism ベースの MVPVM テンプレートを作りました 」で紹介しているテンプレートに含まれているので気になる方はこちらの記事もご覧ください

あとは JsonConvert.SerializeObject メソッドに設定情報を付加してシリアライズ

var json = JsonConvert.SerializeObject(App.AppSettings.Settings, new JsonSerializerSettings()
    {
        Culture = new CultureInfo("ja-JP"),
        DateFormatHandling = DateFormatHandling.MicrosoftDateFormat,
        DateTimeZoneHandling = DateTimeZoneHandling.Local,
        Formatting = Formatting.Indented,
        StringEscapeHandling = StringEscapeHandling.EscapeNonAscii,
    });

StringEscapeHandling = StringEscapeHandling.EscapeNonAscii を設定するとマルチバイト文字がエスケープされるようですね