asp.net core custom model validation output

Starting at asp.net core 2.something, a unified model binding err is return, when input does not bind to an expected model. Api returns 400 with a msg similar to:

{
    "someProperty": [
        "Some error."
    ]
}

There are scenarios however when one may want to return a customised error msg that is used across an application. In order to do this, the following should be done:

Disable the default model validation:

public void ConfigureServices(IServiceCollection services)
{
      //...

      //this should disable the default model validation, so custom attribute can be used instead
      services.Configure<ApiBehaviorOptions>(opts =>
      {
          opts.SuppressModelStateInvalidFilter = true;
      });

      //...
}


Create a custom action filter:

public class ValidateModelFilterAttribute: ActionFilterAttribute
{
    /// 
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        if (!context.ModelState.IsValid)
        {
            var errs = context.ModelState.Keys.Select(
                key => context.ModelState[key].Errors.Select(e =>
                    $"{key}: {(!string.IsNullOrWhiteSpace(e.ErrorMessage) ? e.ErrorMessage : e.Exception.Message)}")
            ).SelectMany(x => x).ToArray();

            context.Result = new ObjectResult(new {Errors: errs})
            {
                StatusCode = (int) HttpStatusCode.BadRequest
            };
        }
    }
}


Decorate controller or method with the custom filter or set it to be used globally.


More info here: https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/filters?view=aspnetcore-2.2

Visual Studio - dump data during a debug session

Depending on a scenario simply paste the code below into the Immediate Window

If you happen to use Newtonsoft.Json:

System.IO.File.WriteAllText(@"c:\temp\debug_dump.json", Newtonsoft.Json.JsonConvert.SerializeObject(obj))

No json serializer? Try xml serializer then:

(new System.Xml.Serialization.XmlSerializer(obj.GetType())).Serialize(new System.IO.StreamWriter(@"c:\temp\debug_dump.xml"), obj)

Obviously the above will throw if an object is not serializable

The Entity Framework provider type 'Npgsql.NpgsqlServices, EntityFramework6.Npgsql' registered in the application config file for the ADO.NET provider with invariant name 'Npgsql' could not be loaded. Make sure that the assembly-qualified name is used and that the assembly is available to the running application

Just wasted way too much time for this:

The Entity Framework provider type 'Npgsql.NpgsqlServices, EntityFramework6.Npgsql' registered in the application config file for the ADO.NET provider with invariant name 'Npgsql' could not be loaded. Make sure that the assembly-qualified name is used and that the assembly is available to the running application. See http://go.microsoft.com/fwlink/?LinkId=260882 for more information.

Obvious perhaps, but not so much anymore while being sure EntityFramework6.Npgsql has been installed... My project used to work a while ago and I could swear I had all the refs intact. After all it would not work otherwise, right...

Anyway, apart from making sure DbProviderFactories and providers are configured, just dbl check EntityFramework6.Npgsql is actually installed / output. If not reinstalling from nuget is a good start. Did work for me ;)