Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why when return interface in a web api method, I get the values of inherited class with interface values?

I have a class that inherited from an Interface , And I am returning interface from my web api get methed , The problem is I am getting values of the inherited class as json string.

This is the interface

 public interface IFoo
    { 
    string A { get ;set ; } 
    string B { get ; set ; } 
    } 

Inherited Class

 public class Child : iFoo
    { 
    string A { get ; set ; } 
    string B { get ; set ; } 
    string C { get ; set ; } 
    string D { get ; set ; } 
    } 

Then I return IFoo from my controller's GetMethod

 public IFoo GetIFoo()
        {
        return  ChildInstance ; 
        }

current result give me all the values of inherited class , and interface both but I want only values that are implemented in interface in json result.

like image 886
Kas Avatar asked Oct 29 '13 08:10

Kas


People also ask

Can an interface be the return type of a method?

You are asking about defining an interface as a return type. If an interface is defined to be the return type of a method then instances of classes derived from that interface can be returned. The benefit of doing that is no different from returning objects of classes derived from a class.

What is return type in ASP NET Core web API?

Specific Type as the Return type in ASP.NET Core Web API. We can return any type of primitive data like string, integer, Boolean, etc., or complex data like Employee, Product, etc, directly from the controller action method. Returning String from ASP.NET Core Web API Controller Action Method:

Can I use an interface as a WebAPI parameter?

Unless you write a custom binder, you can not use an interface as a webapi parameter. As interfaces are abstract and have no constructor, the framework can not create an instance to deserialize to. You should use POCO objects for webapi parameters, and all the properties should be value types or POCO.

Is it possible to deserialize an AS Interface in web API?

As interfaces are abstract and have no constructor, the framework can not create an instance to deserialize to. You should use POCO objects for webapi parameters, and all the properties should be value types or POCO. Note: it is a good practice to have a separate project that defines the parameters and return types, that can be shared.


2 Answers

By the time it hits the Json serializer, it doesn't care what the return type of the method was. All it knows is "I have this object, let's see what I can do with it".

If you want the serializer to only contain the properties that your interface has, you better give it an object that only has the properties that your interface has. You might consider using e.g. Automapper to copy values across from ChildInstance to this new object.

The alternative is more complex - implementing your own serializer so that the Json serializer doesn't get a chance to get involved.

like image 62
Damien_The_Unbeliever Avatar answered Sep 23 '22 12:09

Damien_The_Unbeliever


Your method is contracted to return an object that implements IFoo. It can return any object that implements IFoo, but cannot return an Ifoo itself as you cannot have an instance of an interface. So it returns an instance of Child.

The JSON serializer is then given this instance of Child and uses reflection to work out it's properties. It finds A - D and so serializes them.

If you only want A - B serialised, then you'll have to return an instance of a class that only implements A - B.

Having said all that, if you are using ASP MVC, then check out http://www.creave.dk/post/2009/10/07/Excluding-properties-from-being-serialized-in-ASPNET-MVC-JsonResult.aspx. By changing your class definition to

public class Child : iFoo
{ 
    string A { get ; set ; } 
    string B { get ; set ; }

    [ScriptIgnore]
    string C { get ; set ; } 
    [ScriptIgnore]
    string D { get ; set ; } 
} 

Then you have instructed the JSON serializer to only serialise A - B.

like image 31
David Arno Avatar answered Sep 19 '22 12:09

David Arno