Search code examples
c#.netrestasp.net-web-apijson.net

MissingMemberHandling.Error force exception when deserializing the HTTP body


I am creating a restful web-service using .net and Newtonsoft for serialization/deserialization.

The aim is to force exceptions (preferably HTTP 400) when a required property is not included in the request.

  1. Serializer configuration

    config.Formatters.JsonFormatter.SerializerSettings = new JsonSerializerSettings {
            MissingMemberHandling = MissingMemberHandling.Error,
            Error = delegate (object x, ErrorEventArgs error) {
                System.Diagnostics.Debug.WriteLine (error.ErrorContext.Error);
                throw new Exception("");
        }
    };
    
  2. Model

    [DataContract]
    public class MyObject {
        [JsonProperty(PropertyName = "id", Required = Required.Always)]
        public string Id { get; set; }
    }
    
  3. Restful end-point

    public IHttpActionResult MyAction([FromBody]MyObject request)
    

Testing:

When a request is fired the flow goes like this:

  1. The break point of the error delegate hits ('1. Serializer configuration') and i am able to see the error log. The error is 'swallowed' and the execution is continuing in the controller.
  2. The execution fails in another part of the web service.

Hence... i am able to capture the error using the delegate, but not able to propagate it (not setting a delegate at all again does not make a difference).

Isn't it fair to expect that by setting the 'MissingMemberHandling.Error', i should actually see an error in my controller?

Isn't it fair to expect that by indicating a property as 'required', i should actually see an error in my controller?


Goal:

Instead of silently failing, I would like to force an error when the HTTP body deserialzation fails.


Solution

  • The only legit way i could found to capture missing property errors was to check the ModelState object.

    if (!ModeState.IsValid) {
        return BadRequest(ModelState);
    }
    

    This was added at the top of the controller.


    Update - FluentValidation can be used to:

    • Decouple the validation logic from the actual model.
    • Define more complex validation rules.
    • Automatically return a BadRequest response if the validation fails (which was the initial ask)