Skip to content

ModelState not updating when using JsonPatchDocument.ApplyTo<T>(T, ModelStateDictionary) #1907

Closed
@TheWillieWonkaOfCode

Description

@TheWillieWonkaOfCode

I was playing around with a REST service in ASP.NET Core MVC and found this issue.

Here is my model:

    public class Test
    {
        public int Id { get; set; }

        [Required]
        [StringLength(10, MinimumLength = 1)]
        public string FirstName { get; set; }

        [Required]
        [StringLength(10, MinimumLength = 1)]
        public string LastName { get; set; }

        public Test Copy()
        {
            Test newTest = new Test()
            {
                Id = this.Id,
                FirstName = FirstName,
                LastName = this.LastName
            };

            return newTest;
        }
    }

Here is my POST:

        [HttpPost]
        public IActionResult Create([FromBody] Test item)
        {
            if (item == null) return BadRequest();
            if (!ModelState.IsValid) return BadRequest();

            TestItems.Add(item);

            return CreatedAtRoute("GetTest", new { id = item.Id }, item);
        }

The validation fails correctly based on the attributes on the model.

Here is my PATCH (I have put comments around the issue):

       [HttpPatch("{id}")]
       public IActionResult Patch(string id, [FromBody] JsonPatchDocument<Test> patch)
       {
           int theId;
           if (!int.TryParse(id, out theId)) return BadRequest();
           if (patch == null) return BadRequest();

           Test item = TestItems.GetById(theId);
           if (item == null) return NotFound();

           // This is documented that it's supposed to update the ModelState, but it doesn't appear to do that
           // and the model is always valid even if the updated values are not valid. The ModelState object
           // only contains the id that was passed, it is not validating the parts in the patch instance. V1.1
           // is not GA yet, so it may just be unfinished code.
           patch.ApplyTo(item, ModelState);
           // I shouldn't need to make this call, but the ModelState isn't updated by the ApplyTo call.
           // This correctly updates the ModelState with the errors.
           TryValidateModel(item);
           if (!ModelState.IsValid) return BadRequest();

           TestItems.Update(item);
           return new NoContentResult();
       }

I tried sending a replace for the FirstName to an empty string, and to a string that was too long. In both cases, the ModelState was unchanged after the call to ApplyTo. I added the call to TryValidateModel and that caused the ModelState to then be updated with errors.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions