BumbleBee
BumbleBee

Reputation: 10799

ReadAsAsync - Error : "Type is an interface or abstract class and cannot be instantiated."

I have the below code that gets an object from the web api service.

At the following line of code

response.Content.ReadAsAsync<CMLandingPage>().Result;

I get the following exception :

InnerException = {"Could not create an instance of type MLSReports.Models.IMetaData. Type is an interface or abstract class and cannot be instantiated. Path 'BaBrInfo.Series[0].name', line 1, position 262."}

Any pointers are much appreciated.

 CMLandingPage lpInfo = new CMLandingPage();

            try
            {
                using (HttpClient client = new HttpClient())
                {
                    // Add an Accept header for JSON format
                    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                    response = client.PostAsJsonAsync(LPChartinfoapiURL, criteria.Mlsnums).Result;
                }
                // Throw exception if not a success code.
                response.EnsureSuccessStatusCode();
                // Parse the response body.
                lpInfo = response.Content.ReadAsAsync<CMLandingPage>().Result;
                }

CMLandingPage :

namespace MLSReports.Models
{
    public class CMLandingPage
    {
        public CMLandingPage()  {  }

        public CMColumn BaBrInfo { get; set; }

     }
  public class CMColumnItem<T> : IMetaData
    {
        #region Constructors and Methods
        public CMColumnItem()   {   }
        #endregion

        #region Properties and Fields
        public string name { get; set; }
        public List<T> data { get; set; }
        public string color { get; set; }
        #endregion

    }

    public class CMColumn
    {
        #region Constructor and Method
        public CMColumn()
        {
           Series = new List<IMetaData>();
        }
        #endregion

        #region Properties and Fields
        public string ChartType { get; set; }
        public string ChartTitle { get; set; }
        public List<IMetaData> Series { get; set; }
        #endregion    
    }
}

Upvotes: 1

Views: 3492

Answers (2)

Bronumski
Bronumski

Reputation: 14272

You need to get the serializer to include the type in the json payload and the deserializer to use the included type:

//Serialization
var config = new HttpConfiguration();
config.Formatters.JsonFormatter.SerializerSettings.TypeNameHandling = TypeNameHandling.Auto;
return Request.CreateResponse(HttpStatusCode.OK, dto, config);

//Deserialization
var formatter = new JsonMediaTypeFormatter
{
    SerializerSettings = { TypeNameHandling = TypeNameHandling.Auto }
};
response.Content.ReadAsAsync<CMLandingPage>(new [] { formatter }).Result;

POLYMORPHIC SERIALIZATION USING NEWTON JSON.NET IN HTTPCONTENT

Upvotes: 2

StriplingWarrior
StriplingWarrior

Reputation: 156624

Your CmColumn class has this property on it:

    public List<IMetaData> Series { get; set; }

The WebApi controller is evidently trying to construct an object based on the values of the parameters you're sending it. When it gets to the value with the name "BaBrInfo.Series[0].name", it knows it should create a new IMetaData object so that it can set its name and add it to the Series property, but IMetaData is just an interface: it doesn't know what type of object to construct.

Try changing IMetaData to some concrete type that implements that interface.

Upvotes: 2

Related Questions