1
votes

I'm trying to create an ODataController that supports casting action.

Let's say we have Shape class and Circle class that derives from Shape

namespace NS
{
    public abstract class Shape {    
       int Id; 
       int X;
       int Y; 
     }

     public class Circle : Shape {    
        int Radius;
     }
}

And I want to create controller ShapesController.

public class ShapesController: ODataController
    {
        ShapesContext db = new ShapesContext();

        [EnableQuery]
        public IQueryable<Shape> Get()
        {
            return db.Shapes;
        }
        [EnableQuery]
        public SingleResult<Shape> Get([FromODataUri] int key)
        {
            IQueryable<Shapes> result = db.Shapes.Where(p => p.Id == key);
            return SingleResult.Create(result);
        }
}

Everything work fine for request like

/odata/Shapes
/odata/Shapes(1)

But requests like

/odata/Shapes(1)/NS.Circle

cause 404 error

Referring to routing conventions http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/odata-routing-conventions I have to create action like that

[EnableQuery]
public SingleResult<Circle> GetCircle([FromODataUri] int key)
{
     IQueryable<Shapes> result = db.Shapes.Where(p => p.Id == key).Cast<Circle >;
     return SingleResult.Create(result);
}

But it does not help - 404.

How can i make my controller support casting? Or maybe my approach is completely wrong and I misunderstand the principles?

Thanks

2

2 Answers

0
votes

This sample should work for you:

Supposing I have the following model:

public class Product
{
    public int ID { get; set; }
    public string Name { get; set; }
}

public class Category:Product
{
    public int Price { get; set; }
}

I only need to have this two controller actions both in the ProductsController class:

[EnableQuery]
public IHttpActionResult GetProduct([FromODataUri] int key)
{
    return Ok(Proxy.Products.FirstOrDefault(c => c.ID == key));
}

[EnableQuery]
public IHttpActionResult GetCategory([FromODataUri] int key)
{
    return Ok(Proxy.Products.FirstOrDefault(c => c.ID == key));
}

And both

Products(2)/ODataV4Service.Models.Category

and

Products(2)

will be supported with the correct context URLs respectively.

0
votes

I solved the problem. It was not in controller, it was in the way I was making request. So, everything work fine only if I put / in the end o reqest, like that

/odata/Shapes(1)/NS.Circle/