1
votes

all!

I am using OData v4, Web API 2.2, and an ODataController class. I have implemented the simple Get methods to return a single row and a set of rows. Everything works great when there are rows to be found. But if I change the $filter or specify a key id that does not exist, my application receives status code 500.

Questions:

  1. Should my REST service return 204 or 404? Seems like 500 is bogus.

  2. I have seen examples using EntitySetController. But it seems like the latest OData is using System.Web.OData.* where the EntitySetController example is using System.Web.Http.OData.* - is the latter no longer in use? Should I not use EntitySetController?

  3. What is the best way for me to modify my OData service to return the appropriate status code?

Here is my controller.

using ERSHubRest.Models;

using System.Linq;
using System.Net;
using System.Threading.Tasks;
using System.Web.Http;

using System.Data.Entity;
using System.Data.Entity.Infrastructure;

using System.Web.OData;
using System.Web.OData.Routing;
using System.Web.OData.Query;

using System.Runtime.Serialization;
using System.Collections.Generic;
using System.Security.Claims;
using System.Web.Http;

namespace ERSHubRest.Controllers
{
    public class AppVersionsController : ODataController
    {
        HubModel db = new HubModel();

        private bool AppVersionsExists(System.Guid key)
        {
             return db.AppVersions.Any( p => p.BusinessId == key );
        }

        [EnableQuery]
        public IQueryable<AppVersions> Get()
        {
            if (db.AppVersions.Count() <= 0)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }

            return db.AppVersions;
        }

        [EnableQuery]
        public SingleResult<AppVersions> Get([FromODataUri] System.Guid key)
        {
            IQueryable<AppVersions> result = db.AppVersions.Where( p => p.BusinessId == key );

            if (result == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }

            return SingleResult.Create(result);
        }

        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }
    }
}

Thanks!

Pete

2

2 Answers

2
votes

Use IHttpActionResult as the return type, and then return Ok(object(s)) or NotFound() if there weren't any

OData v3: https://www.nuget.org/packages/Microsoft.AspNet.WebApi.OData/

OData v4: https://www.nuget.org/packages/Microsoft.AspNet.OData/

Make sure to read through the latest features for each. BreezeJs (and other javascript libraries) aren't updated for v4 yet so you'll need to use v3.

v3 doesn't have features like AttributeRouting and other newer stuff so you might want to read up on their differences.

http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api

0
votes

Instead of comparing result to null, simply return the SingleResult:

[EnableQuery]
public SingleResult<AppVersions> Get([FromODataUri] System.Guid key)
{
    IQueryable<AppVersions> result = db.AppVersions.Where( p => p.BusinessId == key );

    return SingleResult.Create(result);
}

.NET will take care of the 404 result for you. You can't compare the result of the Where clause to null because an IQueryable doesn't work that way. It will never be null. You'd have to do result.SingleOrDefault() for that to work, but then you'd lose the IQueryable for the OData functionality.

Not sure why you're getting the 500 error. Maybe using Count explicitly (which, again, is unnecessary) messes up the IQueryable by putting it into an awkward state, but that only accounts for the key-less GET.