简体   繁体   中英

c# REST API polymorphic return type

I have created data contracts as below having inheritance:-

[DataContract(Name = "Animal")]
public class Animal { ... }

[DataContract(Name = "Dog ")]
public class Dog : Animal { // Has some Dog specific member properties }

[DataContract(Name = "Cat ")]
public class Cat : Animal { // Has some Cat specific member properties }

And I'm using ASP.NET WebApi to provide a REST API like:

[HttpGet]
public Task<Animal> Get(string type) 
{ 
    switch(type)
    {
        case "dog":
            Dog dog = GetDogDetails();
            return Task.FromResult(dog);
            break;

        case "cat":
            Cat cat = GetCatDetails();
            return Task.FromResult(cat);
            break:
    }
}

I am not able to return the respective animal types. I get the following error:- "Cannot implicitly convert Dog to Animal".

Also is this polymorphic response a good thing as per REST API standards.

The reason you get this error is because you're returning a Task<T> and task is not covariant. That is, even though Dog is Animal , Task<Dog> is not Task<Animal> .

What can you do?

  1. Change your code to be

      case "dog": Animal dog = GetDogDetails(); return Task.FromResult(dog); break; 

You will lose dog's specific properties though.

  1. Leverage Task<IHttpActionResult> and return Ok(yourObject) .

     [HttpGet] public async Task<IHttpActionResult> Get(string type) { switch(type) { case "dog": Dog dog = GetDogDetails(); return Ok(dog); break; ... } } 

I think you should go the second way.

On a second note, I don't really see any reason to use async/await here. Why would you use Task.FromResult ? If your GetDogDetails method is async , consider awaiting it. I don't think you should worry about Tasks in your current code.

Also is this polymorphic response a good thing as per REST API standards.

I don't know about formal standards but in general it's OK for some objects to have certain properties and for others not to. For instance, imagine a payment system which returns an abstract Event which might or might not have an associated invoice with it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM