ASP.NET Web APIでデータを表示する標準的な方法は、キャメルケースです。ただし、データ形式を別の形式に変更する必要がある場合にタスクが発生することがあります。たとえば、フロントエンドには、スネークケース形式のデータを処理するSPAがある場合があります。この記事では、ASP.NET Core WebAPIでシリアル化形式を変更する方法を紹介します。
この記事では、プロジェクトに転送する必要があるコード例を示します。投稿の最後に、Githubリポジトリへのリンクがあります。ここでは、スネークケースでシリアル化するようにアプリケーションを既に構成しています。すべてのコードサンプルとリポジトリ内のプロジェクトは、ASP.NET Core.net5バージョンで記述されています。
サーバーの要求と応答のシリアル化形式の変更
シリアル化を変更するために必要なのは、アプリケーション設定でネーミングポリシーを設定することだけです。標準ポリシーはキャメルケースです。スネークケースにポリシーをインストールするのは簡単な作業です。
まず、文字列をスネークケースに変換するための実用的なメソッドを追加しましょう。
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using Utils.Helpers;
namespace YourNamespace
{
public static class JsonSerializationExtensions
{
private static readonly SnakeCaseNamingStrategy _snakeCaseNamingStrategy
= new SnakeCaseNamingStrategy();
private static readonly JsonSerializerSettings _snakeCaseSettings = new JsonSerializerSettings
{
ContractResolver = new DefaultContractResolver
{
NamingStrategy = _snakeCaseNamingStrategy
}
};
public static string ToSnakeCase(this T instance)
{
if (instance == null)
{
throw new ArgumentNullException(paramName: nameof(instance));
}
return JsonConvert.SerializeObject(instance, _snakeCaseSettings);
}
public static string ToSnakeCase(this string @string)
{
if (@string == null)
{
throw new ArgumentNullException(paramName: nameof(@string));
}
return _snakeCaseNamingStrategy.GetPropertyName(@string, false);
}
}
}
: , - . SnakeCaseNamingStrategy
. Naming Policy:
using System.Text.Json;
using Utils.Serialization;
namespace YourNamespace
{
public class SnakeCaseNamingPolicy : JsonNamingPolicy
{
public override string ConvertName(string name) => name.ToSnakeCase();
}
}
- ToSnakeCase()
. SnakeCaseNamingPolicy
Startup.cs
ConfigureServices
:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// ...
services
.AddMvc()
.AddJsonOptions(x =>
{
x.JsonSerializerOptions.PropertyNamingPolicy = new SnakeCaseNamingPolicy();
});
// ...
}
}
, Web API, .AddMvc()
.AddControllers()
, . Web API MVC.
JSON Snake Case:
, , …
- , . , Camel Case, . , FirstName LastName Pascal Case, Snake Case. , .
, " " ASP . , :
using System;
using System.Collections.Generic;
using System.Net;
using Microsoft.AspNetCore.Mvc;
namespace YourNamespace
{
public class ValidationProblemDetails : ProblemDetails
{
// 400 status ccode is usually used for input validation errors
public const int ValidationStatusCode = (int)HttpStatusCode.BadRequest;
public ValidationProblemDetails(ICollection validationErrors)
{
ValidationErrors = validationErrors;
Status = ValidationStatusCode;
Title = "Request Validation Error";
}
public ICollection ValidationErrors { get; }
public string RequestId => Guid.NewGuid().ToString();
}
}
, JSON. ProblemDetails
Microsoft.AspNetCore.Mvc
. RequestId UI .
InvalidModelStateResponseFactory
:
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Utils.Serialization;
namespace YourNamespace
{
public class ValidationProblemDetailsResult : IActionResult
{
public async Task ExecuteResultAsync(ActionContext context)
{
var modelStateEntries = context.ModelState
.Where(e => e.Value.Errors.Count > 0)
.ToArray();
var errors = new List();
if (modelStateEntries.Any())
{
foreach (var (key, value) in modelStateEntries)
{
errors.AddRange(value.Errors
.Select(modelStateError => new ValidationError(
name: key.ToSnakeCase(),
description: modelStateError.ErrorMessage)));
}
}
await new JsonErrorResponse(
context: context.HttpContext,
error: new ValidationProblemDetails(errors),
statusCode: ValidationProblemDetails.ValidationStatusCode).WriteAsync();
}
}
}
Startup.cs
:
public class Startup
{
// ...
public void ConfigureServices(IServiceCollection services)
{
// ...
services
.Configure(x =>
{
x.InvalidModelStateResponseFactory = ctx => new ValidationProblemDetailsResult();
});
// ...
}
}
Snake Case :
すべての変更後、アプリケーションはスネークケース形式でJSONデータを送受信するだけでなく、必要な形式で検証エラーも表示します。ここでは、構成されたアプリケーションの例があるリンクからGithubリポジトリを開くことができます。説明されている手順により、Snake Caseだけでなく、他の任意のデータシリアル化形式を適用できます。