Нормализация модели перед проверкой модели в Asp.Net Core 2.0+ - PullRequest
0 голосов
/ 21 ноября 2018

Я использую автоматическая проверка модели (см. «Улучшенная обработка ввода») для поддержания чистоты моих контроллеров;Итак:

[HttpPost]
[ProducesResponseType(typeof(Product), 201)]
public IActionResult Post([FromBody] Product product)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }
    product = _repository.AddProduct(product);
    return CreatedAtAction(nameof(Get), new { id = product.Id }, product);
}

становится:

[HttpPost]
[ProducesResponseType(201)]
public ActionResult<Product> Post(Product product)
{
    _repository.AddProduct(product);
    return CreatedAtAction(nameof(Get), new { id = product.Id }, product);
}

Однако у меня есть несколько моделей, которые имеют свойство phonenumber.Я хотел бы «нормализовать» эти до проверки модели.Я имею в виду, что я хочу нормализовать эти свойства (типа string) из всех видов ввода, например:

  • + 31 23 456 7890
  • (023) 4567890
  • 023 - 4567 890
  • ...

К E.164 запись :

  • + 31234567890

Таким образом, в какой бы форме пользователь ни вводил номер телефона, перед вызовом проверки я хочу быть уверенным, что он всегда находится в форме E.164 («нормализовано»).Как эта нормализация не имеет значения (я использую libphonenumber , если вы настаиваете).В качестве второго, может быть, менее запутанного примера, я могу представить, что строка всегда будет в верхнем / нижнем регистре до вызова валидации.

Какой будет правильный или лучший способ вызвать мой процесс нормализации до проверка вызывается?Должен ли я написать какое-нибудь промежуточное ПО?

Также важно: мои модели содержат атрибуты, поэтому нормализатор знает, какие свойства нужно нормализовать (и как):

class ExampleModel {

    public int Id { get; set; }

    public string Name { get; set; }

    [NormalizedNumber(NumberFormat.E164)]
    public string Phonenumber { get; set; }
}

Я полагаю, промежуточное ПО (? Или каково бы ни было решение) может затем взять модель, выяснить, есть ли у какого-либо свойства (рекурсивно) атрибут и вызвать нормализатор, если необходимо.

1 Ответ

0 голосов
/ 27 ноября 2018

Может быть, вы можете использовать такой подход, используя Formatter.Я использовал аналогичный подход для преобразования всех входящих дат в формат UTC в моем API

public class JsonModelFormatter : JsonMediaTypeFormatter
{
    public override System.Threading.Tasks.Task<Object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger, CancellationToken cancellationToken)
    {

        System.Threading.Tasks.Task<Object> baseTask = base.ReadFromStreamAsync(type, readStream, content, formatterLogger, cancellationToken);

        if (baseTask.Result != null)
        {
            var properties = baseTask.Result.GetType().GetProperties();
            foreach (var property in properties)
            {
                //Check Property attribute and decide if you need to format it
                if (property.CustomAttributes.Where (x=> you condition here))
                {
                    if (property.CanWrite && property.GetValue(baseTask.Result, null) != null)
                    {
                        var propValue = ((string)property.GetValue(baseTask.Result, null));
                       //Update propValue here 
                       property.SetValue(baseTask.Result, newPropValue);
                    }
                }
            }

        }
        return baseTask;
    }

    public override bool CanReadType(Type type)
    {
        return true;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...