2014-10-16 59 views
2

all!我正在使用OData v4构建REST服务。我的表有一个GUID主键。使用GUID主键的OData V4 REST

我的GET和POST请求工作正常。但是,PUT,PATCH和DELETE请求会以404失败。

我不确定url应该是什么样子。我已经在提琴手中尝试过这些,所有404都得到了。我已经用相当多的搜索引擎来搜索这些东西,但没有运气。

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 

这里是我的控制器代码...

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); 
    } 
} 
} 

回答

4

的PATCH请求的URL,PUT和DELETE应该是:

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

的OData使用parenthesizes解决单使用密钥的实体。

更多URL公约,OData的V4 URL约定规范可以被称为:http://docs.oasis-open.org/odata/odata/v4.0/os/part2-url-conventions/odata-v4.0-os-part2-url-conventions.html

+0

我试过这些没有成功。我认为我必须在我的控制器或webapi.config路由中出现错误。 http:// localhost/ershubrest/AppVersions('00000000-E90F-4938-B8F6-000000000000')和http:// localhost/ershubrest/AppVersions(guid'00000000-E90F-4938-B8F6-000000000000') - 结果是404.我将尝试一下控制器和webapi.config,看看我能否找到这个bug。至少我知道我正在使用正确的语法。谢谢! – Pete 2014-10-20 15:26:52

+0

@Pete对不起,我犯了一个错误。如果密钥类型是GUID,则不需要单引号。我纠正了我的答案。如果你发现答案是有用的,你可以接受它或将其标记为有用:) – 2014-10-21 11:27:21

+0

我必须补充说你的实体也应该有Guid键。换句话说,在将密钥存储为字符串时,您不能接受Guid。 – 2015-05-19 10:19:45

4

试试这个: http://localhost/ershubrest/AppVersions(guid '00000000-e90f-4938-b8f6-000000000000')

这应该工作! !

+0

果然,这是为我修复的。不知道什么时候会改变(可能是因为我们现在使用.net 4.5)。但是没有任何工作,直到我尝试过。 – ebol2000 2015-07-09 00:05:00

+0

这是正确的答案。 – 2015-11-24 13:48:48