Haven't checked option #1 yet, but:
- ModelState.ValidationState has 4 possible values (Unvalidated, Invalid, Valid, Skipped) where in case of model binding errors I do get Unvalidated as a value
- Also would consider using ApiBehaviorOptions (see sample here) to automatically return a new BadRequestObjectResult(actionContext.ModelState) - since in case of binding error with a NULL bound value there's nothing to do and in case of validation errors we probably can't do anything either.
Quick notes for the ApiBehaviorOptions:
- must use ApiController attribute (which requires also routing attribute on the controller level also and does alter the way binding works)
- the default behaviour with ApiController attribute will return a BadRequestObjectResult(actionContext.ModelState) without any extra code and configuration
- if you decide to roll your own ApiBehaviorOptions - you must initialize it after service.AddMvc or need to use: services.PostConfigure(o => {}) which has similar effect
- ApiBehaviorOptions SuppressModelStateInvalidFilter has to be false for the InvalidModelStateResponseFactory to work
So in some cases a custom filter is a better solution (less changes).