Search code examples
.netvb.netasp.net-web-apiodata

WebAPI OData GetModel with key strange error


I just create a new WebAPI project (VS2015) with Identity, added a simple test EF model, and scaffold one entity (OData v3):

Public Class LanguagesController
    Inherits ODataController

    Private db As New APITestEntities

    ' GET: odata/Languages
    <EnableQuery>
    Function GetLanguages() As IQueryable(Of Language)
        Return db.Languages
    End Function

    ' GET: odata/Languages(5)
    <EnableQuery>
    Function GetLanguage(<FromODataUri> key As Guid) As SingleResult(Of Language)
        Return SingleResult.Create(db.Languages.Where(Function(language) language.ID = key))
    End Function

...

Well, /odata/Languages returns without errors the Language List, but if I want a SingleResult, calling /odata/Languages(GUID), it returns 400 Bad Request error:

{
  "odata.error": {
    "code": "",
    "message": {
      "lang": "en-US",
      "value": "The request is invalid."
    },
    "innererror": {
      "message": "The parameters dictionary contains a null entry for parameter 'key' of non-nullable type 'System.Guid' for method 'System.Web.Http.SingleResult`1[t.API.Language] GetLanguage(System.Guid)' in 't.API.Controllers.LanguagesController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.",
      "type": "",
      "stacktrace": ""
    }
  }
}

To make it more strange, if I change FromODataUri with FromUri... it works! But what is the point in scaffolding if I need to change every method by hand.

Any one know how can I fix this? I can not believe that this change is the solution.


Solution

  • In OData v3, the syntax for a literal GUID is guid'0308f91a-485f-495f-b725-d92a1f4298f3'; that is, the string guid, followed by a single quote, followed by the GUID digits, followed by a single quote. So your request URI should look like /odata/Languages(guid'0308f91a-485f-495f-b725-d92a1f4298f3').

    Upgrade to OData v4 if you can.