1

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?

5

2 Answers 2

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
            });
    }
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you so much. Can you please explain how can I handle this in ASP.NET Core pipeline? Because I already knew that I had to handle it myself somewhere. I don't know where?
@AliEXE see edit - if it is a webAPI .net core app
Awesome. Yet we do not use Newtonsoft.Json. We use System.Text.Json. Thank you for helping us.
0

Try this nullable operator:

public State? state { get; set; }

1 Comment

Thank you so much. But this is not what I'm searching for. I don't want to change all of my models forcefully. I prefer to configure ASP.NET Core.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.