101 lines
3.3 KiB
C#
101 lines
3.3 KiB
C#
using System.Net.Http.Headers;
|
|
using System.Text.Json;
|
|
using System.Text.Json.Serialization;
|
|
using ApiOPE.Contracts;
|
|
|
|
namespace ApiOPE.Services;
|
|
|
|
public sealed record GenericOperationRequestResult(
|
|
OpeDataEnvelope? Request,
|
|
IReadOnlyDictionary<string, string> Errors)
|
|
{
|
|
public bool IsValid => Request is not null && Errors.Count == 0;
|
|
}
|
|
|
|
public static class GenericOperationRequestReader
|
|
{
|
|
private const string ExpedienteField = "FIELD_0";
|
|
private const string BlockField = "FIELD_1";
|
|
|
|
private static readonly JsonSerializerOptions JsonOptions = new(JsonSerializerDefaults.Web)
|
|
{
|
|
PropertyNameCaseInsensitive = false,
|
|
UnmappedMemberHandling = JsonUnmappedMemberHandling.Disallow,
|
|
MaxDepth = 16
|
|
};
|
|
|
|
public static async Task<GenericOperationRequestResult> ReadAsync(
|
|
HttpRequest request,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
var errors = new Dictionary<string, string>(StringComparer.Ordinal);
|
|
|
|
if (!MediaTypeHeaderValue.TryParse(request.ContentType, out var contentType) ||
|
|
!string.Equals(
|
|
contentType.MediaType,
|
|
OpeMediaTypes.GenericOperationRequest,
|
|
StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
errors[ExpedienteField] = OpeFieldErrors.UnexpectedFormat;
|
|
return new GenericOperationRequestResult(null, errors);
|
|
}
|
|
|
|
OpeDataEnvelope? envelope;
|
|
try
|
|
{
|
|
envelope = await JsonSerializer.DeserializeAsync<OpeDataEnvelope>(
|
|
request.Body,
|
|
JsonOptions,
|
|
cancellationToken);
|
|
}
|
|
catch (JsonException)
|
|
{
|
|
errors[ExpedienteField] = OpeFieldErrors.UnexpectedFormat;
|
|
return new GenericOperationRequestResult(null, errors);
|
|
}
|
|
|
|
if (envelope?.Data is null)
|
|
{
|
|
errors[ExpedienteField] = OpeFieldErrors.Expected;
|
|
errors[BlockField] = OpeFieldErrors.Expected;
|
|
return new GenericOperationRequestResult(null, errors);
|
|
}
|
|
|
|
foreach (var field in envelope.Data)
|
|
{
|
|
if (!string.Equals(field.Key, ExpedienteField, StringComparison.Ordinal) &&
|
|
!string.Equals(field.Key, BlockField, StringComparison.Ordinal))
|
|
{
|
|
errors[field.Key] = OpeFieldErrors.NotExpected;
|
|
continue;
|
|
}
|
|
|
|
if (field.Value is null ||
|
|
!string.Equals(field.Value.Type, "STRING", StringComparison.Ordinal) ||
|
|
string.IsNullOrWhiteSpace(field.Value.Value))
|
|
{
|
|
errors[field.Key] = OpeFieldErrors.UnexpectedFormat;
|
|
continue;
|
|
}
|
|
|
|
if (string.Equals(field.Key, BlockField, StringComparison.Ordinal) &&
|
|
field.Value.Value.Trim() is not ("1" or "2"))
|
|
{
|
|
errors[field.Key] = OpeFieldErrors.UnexpectedFormat;
|
|
}
|
|
}
|
|
|
|
if (!envelope.Data.ContainsKey(ExpedienteField))
|
|
{
|
|
errors[ExpedienteField] = OpeFieldErrors.Expected;
|
|
}
|
|
|
|
if (!envelope.Data.ContainsKey(BlockField))
|
|
{
|
|
errors[BlockField] = OpeFieldErrors.Expected;
|
|
}
|
|
|
|
return new GenericOperationRequestResult(envelope, errors);
|
|
}
|
|
}
|