1.¿Esto es donde debería arrojar excepciones? (No parece un caso excepcional, así que no, pero podría estar equivocado).
Personalmente, siento que debe devolver un objeto con un resultado, así como cualquier error de validación, y no una excepción para la validación de datos, ya sea debido a la falta de información (validación de formato) o validación lógica de negocio. Sin embargo, sugiero lanzar una excepción para errores que no están relacionados con los datos en sí, es decir: si la confirmación de la base de datos falla con datos válidos, etc.
Mi opinión aquí es que la validación no es un "acontecimiento excepcional" . Personalmente, creo que cualquier cosa que un usuario pueda cometer errores al simplemente no ingresar suficientes datos/correctos/etc. es algo que no es excepcional, es una práctica estándar y debe ser manejada directamente por la API.
Las cosas que no están relacionadas con lo que el usuario está haciendo (es decir, problemas de red, problemas del servidor, etc.) son acontecimientos excepcionales y justifican una excepción.
2. ¿Debo utilizar el vacío y un parámetro de "salida"? Si es así, ¿qué tipo debería ser?
3. ¿Debo usar un tipo de devolución de objeto y poner datos allí sobre lo que sucede?
Personalmente prefiero la tercera opción. los parámetros de "salida" no son muy significativos. Además, querrá devolver más de una información de estado única de esta llamada; querrá devolver suficiente información para marcar las propiedades adecuadas como no válidas, así como también toda la información de toda la operación completa.
Esto probablemente requiera una clase que contenga, como mínimo, un estado de confirmación (éxito/error de formato/lógica de negocio fallida/etc.), una lista de asignaciones de propiedades-> errores (es decir: IDataErrorInfo información de estilo), y potencialmente una lista de errores que no están vinculados a una propiedad específica, sino que tratan con la lógica comercial de la operación como un todo, o la combinación de valores de propiedad sugeridos.
4.Alguna otra opción que me he perdido por completo?
La otra opción, que me gusta bastante, es tener la validación en un ensamblaje separado de la capa de procesamiento empresarial. Esto le permite reutilizar la lógica de validación en el lado del cliente.
Lo bueno de esto es que puede simplificar y reducir el tráfico de la red de manera espectacular. El cliente puede pre validar la información y solo enviar datos a través del cable si es válida.
El servidor puede recibir los datos correctos, y volver a validarlos, y devolver nada más que un único resultado de confirmación. Creo que esto debería tener al menos tres respuestas: éxito, error debido a la lógica comercial o error debido al formateo. Esto proporciona seguridad (no es necesario que confíe en el cliente) y le brinda al cliente información sobre lo que no se maneja correctamente, pero evita pasar tanto información incorrecta del cliente-> servidor, como información de validación del servidor-> cliente, por lo que puede reducir drásticamente el tráfico.
La capa de validación puede enviar (con seguridad) la información a la capa CRUD para enviarla.
Gracias por tomarse el tiempo para escribir una respuesta tan detallada. ¿Cuál es, en su opinión, la mejor opción para la mayoría de los casos? Parece que el # 3 es muy popular entre las otras respuestas, ¿estarías de acuerdo en que es la mejor solución para "atrapar a todos"? ¿Especulación de barrado o casos de bordes impares? – Nate
Si le preocupa el tráfico, mi opción 4 es una variación de 3 que proporciona una alternativa "mejor", IMO. También hace que la validación del lado del cliente sea muy sencilla. De lo contrario, la opción 3 es mi favorita. –