[.NET] Как изменить формат данных JSON на Snake Case в ASP.NET Core Web API
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Стандартный способ отображения данных в ASP.NET Web API - это Camel Case. Но иногда возникают задачи, когда нужно изменить формат данных на нечто другое. Например, на фронтенде у вас может быть SPA, которое как раз работает с данными в формате snake case. В этой статье я покажу, как изменить формат сериализации в ASP.NET Core Web API.
Camel case vs Snake caseВ статье приведены примеры кода, которые необходимо будет перенести в свой проект. В конце поста - ссылка на Github репозиторий, где я уже настроил приложение на сериализацию в snake case. Все примеры кода и проект в репозитории написаны на ASP.NET Core версии .net5.Меняем формат сериализации запросов и ответов сервераВсе, что нам нужно сделать для изменения сериализации, это установить Naming Policy в настройках приложения. Стандартный полиси - это Camel Case. Установка полиси на Snake Case - задача несложная.Сначала добавим утилитарные методы для трансформации строк к snake case:
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:
Данные в Snake Case форматеНо когда у нас возникнет ошибка валидация входящих данных, мы обнаружим, что…
Формат выдачи ошибок валидации до сих пор в Camel 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 тоже:
Структура ошибки в формате Snake CaseПосле всех изменений наше приложение теперь не только отдает и принимает JSON данные в формате Snake Case, но и показывает валидационные ошибки тоже в том виде, в котором нам нужно. Здесь по ссылке вы можете открыть Github репозиторий, где есть пример настроенного приложения. По описанным шагам вы можете применить не только Snake Case, но и любой другой формат сериализации данных, который вам по душе.
===========
Источник:
habr.com
===========
Похожие новости:
- [.NET, PowerShell, Visual Studio, C#, F#] Работаем с notebook в VS Code с помощью расширения «dotnet interactive»
- [.NET, IT-инфраструктура, C#, DevOps] ProcInsp — веб-диспетчер задач для Windows
- [.NET, C#, Разработка под Linux, Разработка под Windows] Путешествие в unmanaged code: туда и обратно
- [Программирование, C++, Работа с 3D-графикой, Разработка игр, CGI (графика)] Vulkan. Руководство разработчика. Image view (перевод)
- [Разработка под iOS, Разработка мобильных приложений, Swift] Распознание блоков текста в IOS-приложении с помощью Vision
- [.NET, C#] Делаем фильтры «как в экселе» на ASP.NET Core
- [Информационная безопасность, Программирование, .NET, C#, Разработка под Windows] Как следить (наблюдать) за компьютером. Часть 1 — делаем скриншоты пользователей
- [Программирование, C++, Работа с 3D-графикой, Разработка игр, CGI (графика)] Vulkan. Руководство разработчика. Swap chain (перевод)
- [Программирование, .NET, Разработка под MacOS, Разработка под Windows] От WPF к Авалонии
- [Программирование, .NET, ASP, C#] Что из себя представляет класс Startup и Program.cs в ASP.NET Core (перевод)
Теги для поиска: #_.net, #_.net, #_json, #_asp.net_core, #_tutorial, #_.net
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 14:59
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Стандартный способ отображения данных в ASP.NET Web API - это Camel Case. Но иногда возникают задачи, когда нужно изменить формат данных на нечто другое. Например, на фронтенде у вас может быть SPA, которое как раз работает с данными в формате snake case. В этой статье я покажу, как изменить формат сериализации в ASP.NET Core Web API. Camel case vs Snake caseВ статье приведены примеры кода, которые необходимо будет перенести в свой проект. В конце поста - ссылка на Github репозиторий, где я уже настроил приложение на сериализацию в snake case. Все примеры кода и проект в репозитории написаны на ASP.NET Core версии .net5.Меняем формат сериализации запросов и ответов сервераВсе, что нам нужно сделать для изменения сериализации, это установить Naming Policy в настройках приложения. Стандартный полиси - это Camel Case. Установка полиси на Snake Case - задача несложная.Сначала добавим утилитарные методы для трансформации строк к snake case: 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); } } } using System.Text.Json;
using Utils.Serialization; namespace YourNamespace { public class SnakeCaseNamingPolicy : JsonNamingPolicy { public override string ConvertName(string name) => name.ToSnakeCase(); } } public class Startup
{ public void ConfigureServices(IServiceCollection services) { // ... services .AddMvc() .AddJsonOptions(x => { x.JsonSerializerOptions.PropertyNamingPolicy = new SnakeCaseNamingPolicy(); }); // ... } } Данные в Snake Case форматеНо когда у нас возникнет ошибка валидация входящих данных, мы обнаружим, что… Формат выдачи ошибок валидации до сих пор в Camel 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(); } } 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(); } } } public class Startup
{ // ... public void ConfigureServices(IServiceCollection services) { // ... services .Configure(x => { x.InvalidModelStateResponseFactory = ctx => new ValidationProblemDetailsResult(); }); // ... } } Структура ошибки в формате Snake CaseПосле всех изменений наше приложение теперь не только отдает и принимает JSON данные в формате Snake Case, но и показывает валидационные ошибки тоже в том виде, в котором нам нужно. Здесь по ссылке вы можете открыть Github репозиторий, где есть пример настроенного приложения. По описанным шагам вы можете применить не только Snake Case, но и любой другой формат сериализации данных, который вам по душе. =========== Источник: habr.com =========== Похожие новости:
|
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 14:59
Часовой пояс: UTC + 5