2
votes

I have a similar question to the one here:

OData update controller throwing 415 Unsupported media type error.

I have an OData Web API controller that has a put request to update a Product but so that I don't expose my database entity I would like the put method to accept a ProductDTO instead. Is this possible?

At the moment, I have the following in my ProductsController:

    public IHttpActionResult Put([FromODataUri] int key, ProductDTO product)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        if (key != product.ID)
        {
            return BadRequest();
        }

        Product DBProduct = AsProduct(product);

        db.Entry(DBProduct).State = EntityState.Modified;

        try
        {
            db.SaveChanges();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!ProductExists(key))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }

        return Updated(DBProduct);
    }

And this is my WebApiConfig.cs file:

        builder.EntitySet<Product>("Products");
        builder.EntitySet<ProductDTO>("ProductDTO");

Where Product is:

public class Product
{
    public int ID { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
    public string Category { get; set; }
    public DateTime Timestamp { get; set; }
}

And ProductDTO:

public class ProductDTO
{
    public int ID { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
    public string Category { get; set; }
}

But I get the following message:

The entity type 'ProductService.DTOs.ProductDTO' is not compatible with the base type 'ProductService.Models.Product' of the provided entity set 'Container.Products'. When an entity type is specified for an OData feed or entry reader, it has to be the same or a subtype of the base type of the specified entity set.

There must be a way of doing this...any ideas?

Cheers

2
Changing my WebApiConfig to builder.EntitySet<ProductDTO>("Products"); builder.EntitySet<Product>("ProductsDB"); solves the problem for put but it won't hit my single get method [Queryable] public SingleResult<ProductDTO> GetProduct([FromODataUri] int key) - user2363071

2 Answers

0
votes

You need to

return Updated(product); 

instead of

return Updated(DBProduct);
0
votes

The result needs to not only accept the ProductDTO type, but also return that same type of ProductDTO.

I do this by converting the entity back into the DTO type after it has been processed. This way you can do what Tan Junfu said in their answer:

return Updated(product);

This product could be the result of converting DBproduct back into the DTO type.