A maneira padrão de exibir dados na API da Web ASP.NET é Camel Case. Mas às vezes surgem tarefas quando você precisa alterar o formato dos dados para outro. Por exemplo, no front-end, você pode ter um SPA que funciona com dados no formato de caixa de cobra. Neste artigo, mostrarei como alterar o formato de serialização na API da Web ASP.NET Core.
Este artigo fornece exemplos de código que você precisará transferir para seu projeto. No final da postagem há um link para o repositório Github, onde já configurei o aplicativo para serializar em um caso de cobra. Todos os exemplos de código e o projeto no repositório são escritos na versão ASP.NET Core .net5.
Alterar o formato de serialização de solicitações e respostas do servidor
Tudo o que precisamos fazer para alterar a serialização é definir a Política de Nomenclatura nas configurações do aplicativo. A política padrão é Camel Case. A instalação de uma política em uma caixa Snake é uma tarefa simples.
Primeiro, vamos adicionar métodos utilitários para transformar strings para o caso da cobra:
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 :
Depois de todas as mudanças, nosso aplicativo agora não apenas envia e recebe dados JSON no formato Snake Case, mas também mostra erros de validação na forma em que precisamos. Aqui você pode abrir o repositório Github a partir do link onde há um exemplo de um aplicativo configurado. Por meio das etapas descritas, você pode aplicar não apenas o Snake Case, mas também qualquer outro formato de serialização de dados que desejar.