skip to Main Content

Let’s say I have this model:

public enum State
{
    Valid = 1,
    Invalid = 2
}

public class Person
{
    public string Name { get; set; }
    
    public State state { get; set; }
}

And this controller action:

[HttpPost]
public object SavePerson([FromBody] Person person)
{
    return person;
}

If I send this JSON, everything works just fine:

{
    "name": "John",
    "state": 1
}

However, if I change the "state": 1 to an invalid enumeration like "state": "" or "state": "1", then the person parameter would be null.

In other words, if I send a JSON that is partially valid, ASP.NET Core ignores all fields.

How can I configure ASP.NET Core to at least extract the valid fields from the body?

2

Answers


  1. You need to handle deserialization exception.

    This code will put a default value each time it will encounter a problem in a field but the json string itself must be a valid json string.

        static void Main(string[] args)
        {
            //This should be run on startup code (there are other ways to do that as well - you can put this settings only on controllers etc...)
            JsonConvert.DefaultSettings = () => new JsonSerializerSettings
            {
                Error = HandleDeserializationError
            };
    
            var jsonStr = "{"name": "John","state": "" }";
            var person = JsonConvert.DeserializeObject<Person>(jsonStr);         
    
            Console.WriteLine(JsonConvert.SerializeObject(person)); //{"Name":"John","state":0}
        }
    
        public static void HandleDeserializationError(object sender, ErrorEventArgs args)
        {
            var error = args.ErrorContext.Error.Message;
            args.ErrorContext.Handled = true;
        }
    

    For WebAPI you should have a Startup.cs file looks like this:

        public void ConfigureServices(IServiceCollection services)
        {
            //look for services.AddControllers() -> or add it if it does not exist
            services.AddControllers()
                .AddMvcOptions(options =>
                {
                   //... might have options here
                })
                   //this is what you need to add
                .AddNewtonsoftJson(options =>
                {
                    options.SerializerSettings.Error = HandleDeserializationError
                });
        }
    
    Login or Signup to reply.
  2. Try this nullable operator:

    public State? state { get; set; }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search