I am trying to use Azure Mobile Apps with a Xamarin Forms client and a .net backend. I am using MikeCodesDotNet/App-Service-Helpers to help my get started on the client side. The first Entity I am trying is a simple Game Entity.
When the client loads it makes the GET request to get the Games but it uses updatedAt and it seems like the server wants UpdatedAt.
The request is: http://192.168.0.105/Backend/tables/Game?$filter=(updatedAt%20ge%20datetimeoffset%271970-01-01T00:00:00.0000000%2B00:00%27)&$orderby=updatedAt&$skip=0&$top=50&__includeDeleted=true
which fails with
{ $id: "1", message: "The query specified in the URI is not valid. Could not find a property named 'updatedAt' on type 'Backend.DataObjects.Game'.", exceptionMessage: "Could not find a property named 'updatedAt' on type 'AthelinkBackend.DataObjects.Game'.", exceptionType: "Microsoft.Data.OData.ODataException", stackTrace: " at Microsoft.Data.OData.Query.EndPathBinder.GeneratePropertyAccessQueryForOpenType(EndPathToken endPathToken, SingleValueNode parentNode) at Microsoft.Data.OData.Query.EndPathBinder.BindEndPath(EndPathToken endPathToken, BindingState state) at Microsoft.Data.OData.Query.MetadataBinder.Bind(QueryToken token) at Microsoft.Data.OData.Query.OrderByBinder.ProcessSingleOrderBy(BindingState state, OrderByClause thenBy, OrderByToken orderByToken) at Microsoft.Data.OData.Query.OrderByBinder.BindOrderBy(BindingState state, IEnumerable`1 orderByTokens) at Microsoft.Data.OData.Query.ODataUriParser.ParseOrderByImplementation(String orderBy, IEdmType elementType, IEdmEntitySet entitySet) at System.Web.Http.OData.Query.OrderByQueryOption.get_OrderByClause() at System.Web.Http.OData.Query.Validators.OrderByQueryValidator.Validate(OrderByQueryOption orderByOption, ODataValidationSettings validationSettings) at System.Web.Http.OData.Query.OrderByQueryOption.Validate(ODataValidationSettings validationSettings) at System.Web.Http.OData.Query.Validators.ODataQueryValidator.Validate(ODataQueryOptions options, ODataValidationSettings validationSettings) at System.Web.Http.OData.Query.ODataQueryOptions.Validate(ODataValidationSettings validationSettings) at System.Web.Http.OData.EnableQueryAttribute.ValidateQuery(HttpRequestMessage request, ODataQueryOptions queryOptions) at System.Web.Http.OData.EnableQueryAttribute.ExecuteQuery(Object response, HttpRequestMessage request, HttpActionDescriptor actionDescriptor) at System.Web.Http.OData.EnableQueryAttribute.OnActionExecuted(HttpActionExecutedContext actionExecutedContext)" }
in Chrome but I run the same with UpdatedAt in the GET vars it completes correctly.
I don't know how to resolve this issue or if its a client issue or server issue.
On the Client:
namespace GamesClient.Models
{
public class Game : AppServiceHelpers.Models.EntityData
{
public string Name { get; set; }
public string Type { get; set; }
}
}
On the Server:
namespace Backend.DataObjects
{
public class Game : EntityData
{
public string Name { get; set; }
public string Type { get; set; }
public virtual Collection<Participant> Participants { get; set; }
}
}
namespace Backend.Controllers
{
[AllowAnonymous]
public class GameController : TableController<Game>
{
protected override void Initialize(HttpControllerContext controllerContext)
{
base.Initialize(controllerContext);
MobileServiceContext context = new MobileServiceContext();
DomainManager = new EntityDomainManager<Game>(context, Request, Services);
}
// GET tables/Game
public IQueryable<Game> GetAllGame()
{
return Query();
}
// GET tables/Game/48D68C86-6EA6-4C25-AA33-223FC9A27959
public SingleResult<Game> GetGame(string id)
{
return Lookup(id);
}
// PATCH tables/Game/48D68C86-6EA6-4C25-AA33-223FC9A27959
public Task<Game> PatchGame(string id, Delta<Game> patch)
{
return UpdateAsync(id, patch);
}
// POST tables/Game
public async Task<IHttpActionResult> PostGame(Game item)
{
Game current = await InsertAsync(item);
return CreatedAtRoute("Tables", new { id = current.Id }, current);
}
// DELETE tables/Game/48D68C86-6EA6-4C25-AA33-223FC9A27959
public Task DeleteGame(string id)
{
return DeleteAsync(id);
}
}
}
Update #1
I have checked the database and it looks like the tables are being created correctly. I can even do a POST/INSERT from the Xamarin client which works correctly.
Database tables and data in the Games table
I really think its an issue between UpdatedAt and updatedAt capitalization in the filter on the GET request.
(1) GET from Xamarin Client (which is using updatedAt):
$filter=(updatedAt%20ge%20datetimeoffset%271970-01-01T00:00:00.0000000%2B00:00%27)&$orderby=updatedAt&$skip=0&$top=50&__includeDeleted=true
result in the error message above
(2) GET from Chrome (changing the request to use UpdatedAt) :
$filter=(UpdatedAt%20ge%20datetimeoffset%271970-01-01T00:00:00.0000000%2B00:00%27)&$orderby=UpdatedAt&$skip=0&$top=50&__includeDeleted=true
result in the correct response
[
{
$id: "1",
id: "46d3db2c-c8d4-4a15-8724-d7ce95611a63",
type: "football ",
name: "game1"
},
{
$id: "2",
id: "02d02477-2618-4eda-90ad-34e4117ed423",
type: "basketball ",
name: "game2"
}
]
On the Server side my Game is a child of Microsoft.WindowsAzure.Mobile.Service.EntityData
And on the Client side the Game object is a child of a EntityData class with the following UpdatedAt property definition
[Microsoft.WindowsAzure.MobileServices.UpdatedAt]
public DateTimeOffset UpdatedAt { get; set; }
Also, please let me know which logs I can provide to help, Thanks!