OData V4 REST using GUID primary key
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 !
Pete
Updated on June 04, 2022Comments
-
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 over 9 yearsI 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 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 almost 9 yearsI 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 almost 9 yearsSure 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.