How to fire multiple errors in a single data check using C #

1

I am creating a solution where I would like to keep all business rules within my models including the error response. The problem is that I would also like to be able to capture multiple errors at once like this:

public class Usuario
{
    private int idade;
    public int Idade
    {
        get => idade;
        set
        {
            if (value < 18)
                throw new ArgumentOutOfRangeException("O usuário precisa ter mais que 18 anos.");

            idade = value;
        }
    }

    private string senha;
    public string Senha
    {
        get => senha;
        set
        {
            if (string.IsNullOrWhiteSpace(value) || value.Length < 6 || value.Length > 50)
                throw new ArgumentException("A senha deve ter entre 6 e 50 caracteres.");
            senha = value;
        }
    }
}

I need to make a new instance of this user and feed this information, so that I can return all errors regarding the implementation of the template so that they can be used to inform the user of the model ( which can be an API, a view , or any other), like this:

public class PropertySetError
{
    public string Name { get; set; }
    public ICollection<string> Errors { get; set; }
}

public class Response<T>
{
    public bool Status { get; set; }
    public ICollection<PropertySetError> InvalidProperties { get; set; }
}

public class UsuarioController : ControllerBase
{
    [HttpPost("/usuario")]
    public async Task<ActionResult<Response<Usuario>>> postUsuario([FromBody] JObject obj)
    {
        Usuario usuario = new Usuario();
        object temp = null;
        Response<Usuario> response = new Response<Usuario>();

        try
        {
            foreach(var prop in typeof(Usuario).GetProperties())
            {
                try
                {
                    obj.TryGetValue(prop.Name, out temp);
                    prop.SetValue(usuario, Convert.ChangeType(temp, prop.GetType()));
                }
                catch (Exception)
                {
                    throw;
                }
            }

            response.Status = true;
            return response;
        }
        catch (Exception ex)
        {
            response.Status = false;

            // ... pega todos os possíveis erros aqui e passa para a resposta

            return response;
        }
    }
}
    
asked by anonymous 27.09.2018 / 15:59

1 answer

2
try
{
    obj.TryGetValue(prop.Name, out temp);
    prop.SetValue(usuario, Convert.ChangeType(temp, prop.GetType()));
}
catch (Exception)
{
    throw;
}

This does not make sense, capturing an exception just to throw it again is something wrong. If you have nothing useful to do with the exception do not capture it. The other catch is correct, but avoid capturing Exception , almost always this is an error.

Before using exception, I would study its use more. There are many things here on the site . People abuse to create launch and especially capture exceptions, in this case certainly.

I'm not a fan of throwing an exception in such cases, but being a property gets tricky to do otherwise. And I hope it's just a bad example, because the outside of the track was not made for what was used, there's a misstep too.

The fact that you want to catch multiple exceptions is already indicative that this is not the correct mechanism.

but maybe, and just maybe, you may be wanting to use AggregateException .

I also consider the use of reflection in this case exaggerated, you should have this information at compile time, it is much easier, robust and quick to use them, even if you have to type something else.

    
27.09.2018 / 16:19