Ok finalmente lograron obtener las validaciones de mis modelos de trabajo. Escribí un controlador de validación y un par de métodos de extensiones. Lo primero que el manejador de validación:
public class ValidationHandler<T> : HttpOperationHandler
{
private readonly HttpOperationDescription _httpOperationDescription;
public ValidationHandler(HttpOperationDescription httpOperationDescription)
{
_httpOperationDescription = httpOperationDescription;
}
protected override IEnumerable<HttpParameter> OnGetInputParameters()
{
return _httpOperationDescription.InputParameters
.Where(prm => prm.ParameterType == typeof(T));
}
protected override IEnumerable<HttpParameter> OnGetOutputParameters()
{
return _httpOperationDescription.InputParameters
.Where(prm => prm.ParameterType == typeof(T));
}
protected override object[] OnHandle(object[] input)
{
var model = input[0];
var validationResults = new List<ValidationResult>();
var context = new ValidationContext(model, null, null);
Validator.TryValidateObject(model, context, validationResults,true);
if (validationResults.Count == 0)
{
return input;
}
else
{
var response = new HttpResponseMessage()
{
Content = new StringContent("Model Error"),
StatusCode = HttpStatusCode.BadRequest
};
throw new HttpResponseException(response);
}
}
}
Nótese cómo el controlador recibe un objeto T, esto es principalmente porque me gustaría validar todos los tipos de modelo dentro de la API. Entonces OnGetInputParameters especifica que el manejador necesita recibir un objeto de tipo T, y OnGetOutputParameters especifica que el manejador necesita devolver un objeto con el mismo tipo de T en caso de que se cumplan las políticas de validación, de lo contrario, vea cómo el método on handle arroja un excepción, para que el cliente sepa que ha habido un problema de validación.
Ahora tengo que registrar el controlador, para esto escribí un par de métodos de extensiones, siguiendo un ejemplo de un blog de Pedro Felix http://pfelix.wordpress.com/2011/09/24/wcf-web-apicustom-parameter-conversion/ (este blog me ayudó mucho, hay algunas explicaciones agradables sobre las operaciones de todo el controlador) Así que estos son los métodos de extensiones:
public static WebApiConfiguration ModelValidationFor<T>(this WebApiConfiguration conf)
{
conf.AddRequestHandlers((coll, ep, desc) =>
{
if (desc.InputParameters.Any(p => p.ParameterType == typeof(T)))
{
coll.Add(new ValidationHandler<T>(desc));
}
});
return conf;
}
lo que este Methos comprueba si hay un parámetro de tipo T en las operaciones, y si es así, se añade el manejador a tal operación.
Éste llama al otro método de extensión AddRequestHandler, y ese método agrega el nuevo controlador sin eliminar los registros anteriores, si existen.
public static WebApiConfiguration AddRequestHandlers(
this WebApiConfiguration conf,
Action<Collection<HttpOperationHandler>,ServiceEndpoint,HttpOperationDescription> requestHandlerDelegate)
{
var old = conf.RequestHandlers;
conf.RequestHandlers = old == null ? requestHandlerDelegate :
(coll, ep, desc) =>
{
old(coll, ep, desc);
};
return conf;
}
Lo último es registrar el manejador:
var config = new WebApiConfiguration();
config.ModelValidationFor<T>(); //Instead of passing a T object pass the object you want to validate
routes.SetDefaultHttpConfiguration(config);
routes.MapServiceRoute<YourResourceObject>("SomeRoute");
Así que eso es todo .. Espero que ayuda a otra persona !!
¡Excelente respuesta! – Daniel