Razor Pages で変数やプロパティの値の文字列が実体参照の表記(&#x)で出力される - Razor Pages

Razor Pages でプロパティの値の文字列が実体参照の表記(&#x)で出力される現象と対処法について紹介します。

概要

RazorPageでページモデルクラスのプロパティの値をページに出力すると&#xで始まる実体参照の表記で出力されます。 ページの表示自体には問題ありませんが、コードの視認性を上げたい場合には、実体参照の表記で出力したくない場合があります。 この記事では、実体参照の表記でRazor Pageの出力をしない方法を紹介します。

現象の確認

下記のコードのRazor Pageを準備します。
Razor Page
@page
@model RazorPagesCharacterEntityReference.Pages.pagePMPropertyModel
@{
}
<html>
<head>
  <title>@Model.ProductName の評価</title>
</head>
<body>
  <h2>Razor Pageのテストページ</h2>
  <p>@Model.ProductName はとってもおいしい</p>
</body>
</html>

ページモデルクラス
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace RazorPagesCharacterEntityReference.Pages
{
  public class pagePMPropertyModel : PageModel
  {
    public string ProductName { get; set; }
    public void OnGet()
    {
      ProductName = "ぺんぎんCookie";
    }
  }
}

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

namespace RazorPagesCharacterEntityReference
{
  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();
      });
    }
  }
}

上記のRazor Pageを表示すると下図の結果となります。


出力されるコードは次の通りです。(テキストのコードはエンコードの都合上 "&" を全角文字で表現しています。)
<html>
<head>
  <title>&#x307A;&#x3093;&#x304E;&#x3093;Cookie の評価</title>
</head>
<body>
  <h2>Razor Pageのテストページ</h2>
  <p>&#x307A;&#x3093;&#x304E;&#x3093;Cookie はとってもおいしい</p>
</body>
</html>


ページモデルのプロパティ値の文字列が、&#xnnnn; の形式で表記される、実体参照の表記になっていることがわかります。

Razor Pages内の変数の表現

また、次のRazor Pageのコードの動作も確認します。こちらのページはページモデルクラスのプロパティの値ではなく、Razor Page内の変数の値を ページに表示する動作のコードです。
@page
@model Razor_agesCharset.Pages.page4Model
@{
  string item = "ぺんぎんCookie";
}
<html>
<head>
  <title>@item の評価</title>
</head>
<body>
  <h2>Razor Pageのテストページ</h2>
  <p>@item はとってもおいしい</p>
</body>
</html>

上記のRazor Pageを表示すると下図の結果となります。


出力されるコードは以下です。変数値の文字列は実体参照の表記になっています。
(テキストのコードはエンコードの都合上 "&" を全角文字で表現しています。)
<html>
<head>
  <title>&#x307A;&#x3093;&#x304E;&#x3093;Cookie の評価</title>
</head>
<body>
  <h2>Razor Pageのテストページ</h2>
  <p>&#x307A;&#x3093;&#x304E;&#x3093;Cookie はとってもおいしい</p>
</body>
</html>


ページ自体は正しく表示されますが、HTMLのコードで実体参照の文字列表記にしたくない場合があります。
以下、対処方法を紹介します。

対処法1: TextEncoderSettings を設定する

ASP.NET Core アプリケーションの開始時にServiceCollection.ConfigureのWebEncoderOptionsオブジェクトのTextEncoderSettingsを設定します。

Program.cs または、Startup.csファイルのコードを修正します。

.NET 6形式のコードの場合

Program.cs
using Microsoft.Extensions.WebEncoders;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
//追加
builder.Services.Configure<WebEncoderOptions>(options => {
  options.TextEncoderSettings = new System.Text.Encodings.Web.TextEncoderSettings(System.Text.Unicode.UnicodeRanges.All);
});
var app = builder.Build();

app.UseRouting();
app.MapRazorPages();
app.Run();

.NET 5形式のコードの場合

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

namespace RazorPagesCharacterEntityReference
{
  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();

      //追加
      services.Configure<WebEncoderOptions>(options => {
        options.TextEncoderSettings = new System.Text.Encodings.Web.TextEncoderSettings(System.Text.Unicode.UnicodeRanges.All);
      });
    }

    // 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();
      });
    }
  }
}

ConfigureServicesメソッドに以下のコードを追記します。TextEncoderSettings に UnicodeRanges.All の TextEncoderSettingsを設定すると実行時のエンコーディングが 実体参照のエンコードでなくなります。
  builder.Services.Configure<WebEncoderOptions>(options => {
    options.TextEncoderSettings = new System.Text.Encodings.Web.TextEncoderSettings(System.Text.Unicode.UnicodeRanges.All);
  });

実行結果

上記のWebアプリを実行します。ページを表示します。


ソースコードを確認すると、実体参照のエンコーディングされていないことが確認できます。

出力されるコードは以下です。
<html>
<head>
  <title>ぺんぎんCookie の評価</title>
</head>
<body>
  <h2>Razor Pageのテストページ</h2>
  <p>ぺんぎんCookie はとってもおいしい</p>
<script src="/_framework/aspnetcore-browser-refresh.js"></script></body>
</html>



RazorPages内の変数の値の場合も、実体参照のエンコーディングされていないことが確認できます。



補足:その他の設定

すべての文字を実体参照にしたい場合

すべての文字を実体参照の表現にしたい場合は、UnicodeRanges.None を設定します。
  builder.Services.Configure<WebEncoderOptions>(options => {
    options.TextEncoderSettings = new System.Text.Encodings.Web.TextEncoderSettings(System.Text.Unicode.UnicodeRanges.None);
  });

変数の値はすべて実体参照の表現で出力されています。

アルファベット以外の文字を実体参照にしたい場合

アルファベット以外の文字を実体参照の表現にしたい場合は、UnicodeRanges.BasicLatin を設定します。
  builder.Services.Configure<WebEncoderOptions>(options => {
    options.TextEncoderSettings = new System.Text.Encodings.Web.TextEncoderSettings(System.Text.Unicode.UnicodeRanges.BasicLatin);
  });

変数の値はアルファベット部分の"Cookie"以外はすべて実体参照の表現で出力されています。

漢字以外の文字を実体参照にしたい場合

漢字以外の文字を実体参照の表現にしたい場合は、UnicodeRanges.CjkUnifiedIdeographs または UnicodeRanges.CjkUnifiedIdeographsExtensionA を設定します。
  builder.Services.Configure<WebEncoderOptions>(options => {
    options.TextEncoderSettings = new System.Text.Encodings.Web.TextEncoderSettings(System.Text.Unicode.UnicodeRanges.CjkUnifiedIdeographs);
  });

変数に漢字を入れて確認します。
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace RazorPagesCharacterEntityReferenceNet6.Pages
{
  public class page_pm_propertyModel : PageModel
  {
    public string ProductName { get; set; }
    public void OnGet()
    {
      ProductName = "高級、ぺんぎんCookie";
    }
  }
}

ページの表示は下図です。


変数の値は漢字の"高級"以外はすべて実体参照の表現で出力されています。

漢字、ひらがな、かたかな、アルファベットなどの日本語以外の文字を実体参照にしたい場合

漢字、ひらがな、かたかな、アルファベットなどの日本語以外の文字を実体参照にしたい場合は、次のコードを利用します。
builder.Services.Configure<WebEncoderOptions>(options => {
  options.TextEncoderSettings = new System.Text.Encodings.Web.TextEncoderSettings(
    System.Text.Unicode.UnicodeRanges.BasicLatin,
    System.Text.Unicode.UnicodeRanges.Hiragana,
    System.Text.Unicode.UnicodeRanges.Katakana,
    System.Text.Unicode.UnicodeRanges.CjkCompatibility,
    System.Text.Unicode.UnicodeRanges.CjkCompatibilityForms,
    System.Text.Unicode.UnicodeRanges.CjkCompatibilityIdeographs,
    System.Text.Unicode.UnicodeRanges.CjkRadicalsSupplement,
    System.Text.Unicode.UnicodeRanges.CjkStrokes,
    System.Text.Unicode.UnicodeRanges.CjkSymbolsandPunctuation,
    System.Text.Unicode.UnicodeRanges.CjkUnifiedIdeographs,
    System.Text.Unicode.UnicodeRanges.CjkUnifiedIdeographsExtensionA,
    System.Text.Unicode.UnicodeRanges.EnclosedCjkLettersandMonths
    );
});

変数にアラビア文字を入れて確認します。
  public class page_pm_propertyModel : PageModel
  {
    public string ProductName { get; set; }
    public void OnGet()
    {
      ProductName = "高級、ぺんぎんCookie مشروبات";
    }
  }

ページの表示は下図です。


アラビア文字部分が実体参照の表現です。それ以外の文字は実体参照の表現にはなっていません。

対処法2: Html.Raw() を利用する

Html.Raw メソッドを利用して出力すると、実体参照の表記にならずに出力できます。

コード

下記のRazor Pageのコードを準備します。
Razor Page
@page
@model Razor_agesCharset.Pages.page3Model
@{
}
<html>
<head>
  <title>@Html.Raw(Model.ProductName)の評価</title>
</head>
<body>
  <h2>Razor Pageのテストページ</h2>
  <p>@Html.Raw(Model.ProductName)はとってもおいしい</p>
</body>
</html>
ページモデルクラス
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace Razor_agesCharset.Pages
{
    public class page3Model : PageModel
    {
    public string ProductName { get; set; }
    public void OnGet()
    {
      ProductName = "ぺんぎんCookie";
    }
  }
}

表示結果

上記のRazor Pageを表示すると下図の結果となります。



<html>
<head>
  <title>ぺんぎんCookieの評価</title>
</head>
<body>
  <h2>Razor Pageのテストページ</h2>
  <p>ぺんぎんCookieはとってもおいしい</p>
</body>
</html>
著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
最終更新日: 2022-12-12
改訂日: 2022-12-12
作成日: 2021-10-11
iPentec all rights reserverd.