简体   繁体   中英

.NET Web API (not Core) - Creating a Patch operation in an Entity Framework controller

I'm using Entity Framework in a .NET Web API (not Core) project with an Angular front end. Currently, the only examples of patch implementation I can find is for ASP.Net Core products - so I'd firstly like confirm if patch is even possible in plain ol' ASP.Net Web API (not Core) .

I'd like to implement patch in some of my controllers, but by default, the Entity controller does not seem to come with code for a patch operation. Instead it comes with GET , PUT , POST and DELETE . What code is needed in my Entity controller so that patch requests are valid? Is there a way to specify this when adding a new Entity controller, or must it always be entered in manually?

My controller:

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Description;
using api.Models;
using api.Models.my_model;
using System.Net.Mail;
using System.Configuration;

namespace api.Controllers.my_model
{
    public class myController : ApiController
    {
        private myCodeFirst db = new myCodeFirst();

        // GET: api/my
        public IQueryable<myTable> GetmyTable()
        {
            return db.myTable;
        }

        // GET: api/my/5
        [ResponseType(typeof(myTable))]
        public IHttpActionResult GetmyTable(int id)
        {
            myTable myTable = db.myTable.Find(id);
            if (myTable == null)
            {
                return NotFound();
            }

            return Ok(myTable);
        }

        // PUT: api/my/5
        [ResponseType(typeof(void))]
        public IHttpActionResult PutmyTable(int id, myTable myTable)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            if (id != myTable.ID)
            {
                return BadRequest();
            }

            db.Entry(myTable).State = EntityState.Modified;

            try
            {
                db.SaveChanges();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!myTableExists(id))
                {
                    return NotFound();
                }
                else
                {
                    throw;
                }
            }

            return StatusCode(HttpStatusCode.NoContent);
        }

        // POST: api/my
        [ResponseType(typeof(myTable))]
        public IHttpActionResult PostmyTable(myTable myTable)
        {

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

            db.myTable.Add(myTable);


            db.SaveChanges();


            return CreatedAtRoute("DefaultApi", new { id = myTable.ID }, myTable);
        }

        // DELETE: api/my/5
        [ResponseType(typeof(myTable))]
        public IHttpActionResult DeletemyTable(int id)
        {
            myTable myTable = db.myTable.Find(id);
            if (myTable == null)
            {
                return NotFound();
            }

            db.myTable.Remove(myTable);
            db.SaveChanges();

            return Ok(myTable);
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }

        private bool myTableExists(int id)
        {
            return db.myTable.Count(e => e.ID == id) > 0;
        }


    }



}

The PATCH method is a request method supported by the HTTP protocol for making partial changes to an existing resource. There is some JSON Patch operations you can see:

Add

{
    "op": "add",
    "path": "/a/b",
    "value": "foo"
}

Remove

{
    "op": "remove",
    "path": "/a/b"
}

Replace

{
    "op": "replace",
    "path": "/a/b",
    "value": "foo"
}

Copy

{
    "op": "copy",
    "from": "/a/b",
    "path": "/a/c"
}

Move

{
    "op": "move",
    "from": "/a/b",
    "path": "/a/c"
}

Test

{
    "op": "test",
    "path": "/a/b",
    "value": "foo"
}

In ASP.NET Core you specify patch methods with [HttpPatch] attribute. For getting data in this methods you should use JsonPatchDocument<TModel> exist in Microsoft.ApsNetCore.JsonPatch namespace where TModel is your entity that you want convert to it. Another package that will be useful is AutoMapper. You can install it from NuGet package manager as below:

Install-Package AutoMapper

and referenced it in your controller.

Now it's time to look at an example in ASP.NET Core Web API:

public async Task<IActionResult> PartiallyUpdateBook([FromRoute] Guid id, [FromBody] JsonPatchDocument<BookModel> patchDoc)
{
    // If the received data is null
    if (patchDoc == null)
    {
        return BadRequest();
    }

    // Retrieve book from database
    var book = await _context.Books.SingleOrDefaultAsync(x => x.Id == id)

    // Check if is the book exist or not
    if (book == null)
    {
        return NotFound();
    }

    // Map retrieved book to BookModel with other properties (More or less with eexactly same name)
    var bookToPatch = Mapper.Map<BookModel>(book);

    // Apply book to ModelState
    patchDoc.ApplyTo(bookToPatch, ModelState);

    // Use this method to validate your data
    TryValidateModel(bookToPatch);

    // If model is not valid, return the problem
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }

    // Assign entity changes to original entity retrieved from database
    Mapper.Map(bookToPatch, book);

    // Say to entity framework that you have changes in book entity and it's modified
    _context.Entry(book).State = EntityState.Modified;

    // Save changes to database
    await _context.SaveChangesAsync();

    // If everything was ok, return no content status code to users
    return NoContent();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM