appsettings.json に日本語(マルチバイト文字)の文字列を値に設定すると文字化けする - C#

appsettings.json に日本語(マルチバイト文字)の文字列を値に設定すると文字化けする現象について紹介します。

現象の確認:RazorPagesの例

以下のコードを記述します。

コード

Startup.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace AppSettingsAspNetRazorPages
{
  public class Startup
  {
    // This method gets called by the runtime. Use this method to add services to the container.
    // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
    public void ConfigureServices(IServiceCollection services)
    {
      services.AddRazorPages();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
      if (env.IsDevelopment()) {
        app.UseDeveloperExceptionPage();
      }

      app.UseRouting();
      app.UseEndpoints(endpoints =>
      {
        endpoints.MapRazorPages();
      });
    }
  }
}
test-01.cshtml
@page
@model AppSettingsAspNetRazorPages.Pages.test_01Model
@{
}
<html>
<head>

</head>
<body>
  <h2>appsettings.jsonのデモ</h2>
  <p>@Model.Stringvalue1</p>
</body>
</html>
test-01.cshtml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Configuration;

namespace AppSettingsAspNetRazorPages.Pages
{
  public class test_01Model : PageModel
  {
    public string Stringvalue1 { get; set; }
    private readonly IConfiguration _conf;

    public test_01Model(IConfiguration configuration)
    {
      _conf = configuration;      
    }

    public void OnGet()
    {
      Stringvalue1 = _conf.GetSection("AppConfiguration")["string01"];
    }
  }
}
appsettings.json
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "AppConfiguration": {
    "string01": "ぺんぎんクッキー"
  }
}

解説

コードのロジックの詳細はこちらの記事を参照してください。

実行結果

上記のプロジェクトを実行します。Webブラウザで、(アプリケーションルートURL)/test-01 のURLを開きます。下図のページが表示されます。
appsettings.jsonの値が文字化けされてページに表示されています。

原因

appsettings.json が Shift-JIS または ANSI でエンコーディングされている可能性があります。

対処法

appsettings.jsonをUnicode UTF-8 でエンコーディングで保存します。

Visual Studio で appsettings.json ファイルを開きます。


[ファイル]メニューの[名前を付けて appsettings.json を保存]の項目をクリックします。


[名前を付けてファイルを保存]ダイアログが表示されます。


ダイアログ右下の[上書き保存]ボタンの右側の下三角ボタンをクリックします。下図のドロップダウンメニューが表示されます。メニューの[エンコード付きで保存]の項目をクリックします。


[保存オプションの詳細設定]ダイアログが表示されます。


[エンコード]のコンボボックスをクリックします。下図のドロップダウンリストが表示されます。


リストから "Unicode (UTF-8 シグネチャ付き) - コードページ 65001" の項目を選択します。選択後、ダイアログの[OK]ボタンをクリックします。


なお、次のエンコードであれば文字化けせずにappsettins.json に設定したマルチバイト文字列を表示できます。
  • Unicode (UTF-8 シグネチャ付き) - コードページ 65001
  • Unicode (UTF-8 シグネチャなし) - コードページ 65001
  • Unicode - コードページ 1200
  • Unicode (Big-Endian) - コードページ 1201

プロジェクトを再度実行し、Webブラウザで、(アプリケーションルートURL)/test-01 のURLを開きます。下図のページが表示されます。
文字化けせずに、appsettings.json に設定した値が表示されることが確認できます。

ASP.NET Core アプリケーションの場合

RazorPagesを利用しないASP.NET Coreアプリケーションの場合も同様の対処法で解決できます。

コード

appsettings.json ファイルはUTF-8または、Unicodeで保存します。
appsettings.json
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "AppConfiguration": {
    "Value1": "Penguin Cookie",
    "Value2": "ぺんぎんクッキー",
    "Value3": "CD-A100"
  }
}
Program.cs
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace AppSettingsAspNetCore
{
  public class Program
  {
    public static void Main(string[] args)
    {
      CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
              webBuilder.UseStartup<Startup>();
            });
  }
}
Startup.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;

namespace AppSettingsAspNetCore
{
  public class Startup
  {
    private readonly IConfiguration _configuration;
    public Startup(IConfiguration configuration)
    {
      _configuration = configuration;
    }

    // This method gets called by the runtime. Use this method to add services to the container.
    // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
    public void ConfigureServices(IServiceCollection services)
    {
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
      if (env.IsDevelopment()) {
        app.UseDeveloperExceptionPage();
      }

      app.UseRouting();

      app.UseEndpoints(endpoints =>
      {
        endpoints.MapGet("/", async context =>
              {
                context.Response.ContentType = "text/plain; charset=utf-8";

                string value1 = _configuration.GetSection("AppConfiguration")["Value1"];
                string value2 = _configuration.GetSection("AppConfiguration")["Value2"];
                string value3 = _configuration.GetSection("AppConfiguration")["Value3"];

                await context.Response.WriteAsync("Hello World!\r\n");
                await context.Response.WriteAsync("value1:" + value1 + "\r\n");
                await context.Response.WriteAsync("value2:" + value2 + "\r\n");
                await context.Response.WriteAsync("value3:" + value3 + "\r\n");
              });
      });
    }
  }
}

実行結果

appsettings.json ファイルをUnicodeまたはUTF-8で保存し、 プロジェクトを実行すると文字化けせずにappsettings.jsonの内容を表示できます。

補足:ASP.NET CoreアプリケーションのHTML出力で文字化けする場合

上記の対策を実施した場合でも、ASP.NET Core アプリケーションでHTMLのレスポンスをすると文字化けする場合があります。

現象の確認

以下のコードを準備します。
appsettings.json
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "AppConfiguration": {
    "Value1": "Penguin Cookie",
    "Value2": "ぺんぎんクッキー",
    "Value3": "CD-A100"
  }
}
Program.cs
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

IConfiguration configuration = new ConfigurationBuilder()
      .AddJsonFile("appsettings.json", true, true)
      .Build();

IConfigurationSection section = configuration.GetSection("AppConfiguration");
string outHtml = "<html>"
  + "<head></head>"
  + "<body>"
  + "<p>value1:" + section["Value1"] + "</p>"
  + "<p>value2:" + section["Value2"] + "</p>"
  + "<p>value3:" + section["Value3"] + "</p>"
  + "</body>"
  + "</html>";
app.MapGet("/", (HttpContext context) => {
  context.Response.ContentType = "text/html";
  return outHtml;
});

app.Run();

上記のコードでプロジェクトを実行すると、下図のページが表示されます。日本語文字列(マルチバイト文字)が文字化けしています。

原因

HTML出力で文字化けが発生する場合は、Webブラウザのエンコーディングがマルチバイト文字のエンコーディングと一致していない可能性があります。

対処法

HTML出力で明示的にエンコーディングを指定するコードを追加します。出力のHTMLタグのHeadに次のタグを挿入します。
<meta http-equiv="content-type" content="text/html; charset=utf-8" />

コード(修正版)

Program.csファイルのコードを以下のコードに変更します。 headタグ内に先に紹介したmetaタグを出力します。
Program.cs
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

IConfiguration configuration = new ConfigurationBuilder()
      .AddJsonFile("appsettings.json", true, true)
      .Build();

IConfigurationSection section = configuration.GetSection("AppConfiguration");
string outHtml = "<html>"
  + "<head><meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\" /></head>"
  + "<body>"
  + "<p>value1:" + section["Value1"] + "</p>"
  + "<p>value2:" + section["Value2"] + "</p>"
  + "<p>value3:" + section["Value3"] + "</p>"
  + "</body>"
  + "</html>";
app.MapGet("/", (HttpContext context) => {
  context.Response.ContentType = "text/html";
  return outHtml;
});

app.Run();

実行結果

修正したコードでプロジェクトを実行すると、下図のページが表示されます。日本語文字列(マルチバイト文字)が文字化けせずに表示できます。

著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
最終更新日: 2022-11-01
作成日: 2021-08-01
iPentec all rights reserverd.