OData V4 REST using GUID primary key

10,069

Solution 1

The request URL for PATCH, PUT and DELETE should be:

http://localhost/ershubrest/AppVersions(00000000-e90f-4938-b8f6-000000000000)

OData is using parenthesizes for addressing single entities using keys.

For more URL conventions, the OData V4 URL convention spec can be referred to: http://docs.oasis-open.org/odata/odata/v4.0/os/part2-url-conventions/odata-v4.0-os-part2-url-conventions.html

Solution 2

Try this: http://localhost/ershubrest/AppVersions(guid'00000000-e90f-4938-b8f6-000000000000')

That should work!!

Solution 3

Odata V1-3 : http://localhost/ershubrest/AppVersions(guid'00000000-e90f-4938-b8f6-000000000000')

Odata V4 : http://localhost/ershubrest/AppVersions(00000000-e90f-4938-b8f6-000000000000)

I've tested Odata for 2 days

I ensure that !

Share:
10,069
Pete
Author by

Pete

Updated on June 04, 2022

Comments

  • Pete
    Pete almost 2 years

    all! I am using OData v4 building REST services. My tables have a GUID primary key.

    My GET and POST requests are working fine. But the PUT, PATCH, and DELETE requests fail with 404.

    I am not sure what the url should look like. I've tried these in Fiddler, all getting the 404. I have googled this quite a bit with no luck.

    http://localhost/ershubrest/AppVersions/guid'00000000-e90f-4938-b8f6-000000000000'
    
    http://localhost/ershubrest/AppVersions/'00000000-e90f-4938-b8f6-000000000000'
    
    http://localhost/ershubrest/AppVersions/00000000-e90f-4938-b8f6-000000000000
    

    Here is the code for my controller...

    using ERSHubRest.Models;
    using System.Data.Entity;
    using System.Data.Entity.Infrastructure;
    using System.Linq;
    using System.Net;
    using System.Threading.Tasks;
    using System.Web.Http;
    using System.Web.OData;
    using System.Web.OData.Query; 
    using System.Web.OData.Routing;
    
    namespace ERSHubRest.controllers
    {
    [ODataRoutePrefix("AppVersions")]
    public class AppVersionsController : ODataController
    {
        HubModel db = new HubModel();
    
        private bool AppVersionsExists(System.Guid key)
        {
            return db.AppVersions.Any(p => p.AppVersionId == key);
        }
    
        // http GET for select queries
    
        [ODataRoute]
        [EnableQuery]
        public IQueryable<AppVersions> Get()
        {
            return db.AppVersions;
        }
    
        [ODataRoute("({key})")]
        [EnableQuery]
        public IHttpActionResult Get([FromODataUri] System.Guid key)
        {
            IQueryable<AppVersions> result = db.AppVersions.Where(p => p.BusinessId == key);
    
            if (result == null)
            {
                return NotFound();
            }
    
            return Ok(result);
        }
    
        // http POST for insert
    
        [ODataRoute()]
        [HttpPost]
        [EnableQuery(AllowedQueryOptions = AllowedQueryOptions.All)]
        public async Task<IHttpActionResult> Post(AppVersions appVersions)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }
            db.AppVersions.Add(appVersions);
            await db.SaveChangesAsync();
            return Created(appVersions);
        }
    
        // http PUT and PATCH for updates
    
        [ODataRoute()]
        [HttpPatch]
        [EnableQuery(AllowedQueryOptions = AllowedQueryOptions.All)]
        public async Task<IHttpActionResult> Patch([FromODataUri] System.Guid key, Delta<AppVersions> appVersions)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }
            var entity = await db.AppVersions.FindAsync(key);
            if (entity == null)
            {
                return NotFound();
            }
            appVersions.Patch(entity);
            try
            {
                await db.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!AppVersionsExists(key) )
                {
                    return NotFound();
                }
                else
                {
                    throw;
                }
            }
            return Updated(entity);
        }
    
        [ODataRoute()]
        [HttpPut]
        [EnableQuery(AllowedQueryOptions = AllowedQueryOptions.All)]
        public async Task<IHttpActionResult> Put([FromODataUri] System.Guid key, AppVersions update)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }
            if ( ! key.Equals( update.BusinessId ))
            {
                return BadRequest();
            }
            if (!AppVersionsExists(key))
            {
                return BadRequest();
            }
            db.Entry(update).State = EntityState.Modified;
            try
            {
                await db.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                if ( ! AppVersionsExists(key))
                {
                    return NotFound();
                }
                else
                {
                    throw;
                }
            }
            return Updated(update);
        }
    
        // last is Delete
    
        [ODataRoute()]
        [HttpDelete]
        [EnableQuery(AllowedQueryOptions = AllowedQueryOptions.All)]
        public async Task<IHttpActionResult> Delete([FromODataUri] System.Guid key)
        {
            var appVersions = await db.AppVersions.FindAsync(key);
            if (appVersions == null)
            {
                return NotFound();
            }
            db.AppVersions.Remove(appVersions);
            await db.SaveChangesAsync();
            return StatusCode(HttpStatusCode.NoContent);
        }
    
        // clean up 
    
        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }
    }
    }
    
  • Pete
    Pete over 9 years
    I have tried these with no success. I think that I must have an error in my controller or webapi.config routes. localhost/ershubrest/… and localhost/ershubrest/… - result was the 404. I will experiment with the controller and webapi.config a bit to see if I can find the bug. At least I know that I am using the correct syntax. Thanks!
  • Yi Ding - MSFT
    Yi Ding - MSFT over 9 years
    @Pete Sorry that I made a mistake. If the key type is a GUID, the single quotes are not needed. I've corrected my answer. If you find the answer is useful, you can accept it or mark it as useful :)
  • Ivan Nikitin
    Ivan Nikitin almost 9 years
    I must add that your Entity should also have Guid key. In other words, you cannot accept Guid while storing the key as a string.
  • ebol2000
    ebol2000 almost 9 years
    Sure enough, this is what fixed it for me. Not sure when this would have changed (perhaps because we're now using .net 4.5). But nothing worked until I tried this.