The automatic server side Model validation will not apply, because we got a "Delta" object, that means, a PARTIAL object, which by definition is not a valid Model (alas!, it is partial!!! (so it has for example required fields missing))
Let's see for example a PARTIAL update using the HTTP PATCH verb. We have written a Patch() Action Method as follows. To make the validation of the object, we do not use the "IsValid" property of the ModelState, but we validate manually the received entity, using a BodyModelValidator :
(COPY-PASTE THIS CODE) :
[EnableQuery(AllowedQueryOptions = AllowedQueryOptions.All)] public IHttpActionResult Patch([FromBody] Delta<Note> note) { if (note == null) { return StatusCode(HttpStatusCode.BadRequest); } Note original = Repository.Get(note.GetEntity().ID); note.Patch(original);
string errors = String.Empty; var modelValidator = Configuration.Services.GetBodyModelValidator(); var metadataProvider = Configuration.Services.GetModelMetadataProvider(); bool isValid = modelValidator.Validate(original, typeof(Note), metadataProvider, this.ActionContext, String.Empty); if (!isValid) { errors = this.ModelState.Keys.SelectMany(key => this.ModelState[key].Errors) .Select(error => error.ErrorMessage).Aggregate((i, j) => i + ", " + j); }
return isValid ? StatusCode(HttpStatusCode.OK) as IHttpActionResult : BadRequest(errors); }
After we get the entity to update from database, we call the Patch() method, which takes care of performing the required update of the modified properties:
We are using the BodyModelValidator's Validate() method together with a ModelMetadataProvider, to check if the Delta object that we got is valid, and complains with the Data Annotations. If it don't, we concatenate in a string the errors found, and render a BadRequest status response together with the errors found:
Now in order to test our ODataController, we will send an HTTP PATCH request using Fiddler , containing a JSON entity in the Body. Remember to set the "Content-Type" to JSON at the request's header:
We got a response with OK status, because our Patch() renders an IHttpActionResult using the OK (200) Status Code .
But if we send a PATCH request inconsistent with the Data Annotations that we set, the request will be rejected:
After the request was rejected , we got an 400 status code or "Bad Request" response containing the error message informing us of what was illegal input:
That's all
In this post we've seen how we perform Model Validation on a Web API OData v4.0 RESTful with ODataController for HTTP PATCH requests, fixing an ODataController whose PATCH (or PUT) method which is not working properly, considering always the Model as valid , even if it does not comply with the Model's Data Annotations.. Enjoy programming.....
By Carmel Shvartzman
כתב: כרמל שוורצמן
No comments:
Post a Comment