Search code examples
asp.netjurassic

ASP.NET Web API returning C# class


In Web API Controller action method returns C# class, like that:

public class ShipController : ApiController
{
    [HttpGet]
    public Cell GetShip()
    {
        return new Cell(new ScriptEngine());
    }
}

Where Cell is my class, inherited from ObjectInstance from Jurassic JS library. When I call this action, ASP.NET tries to serialize my object to XML or JSON, and I get System.InvalidOperationException: "The 'ObjectContent`1' type failed to serialize the response body for content type 'application/xml; charset=utf-8'." I also tried to add [DataContract] attributes to class, as I found here, like that:

[DataContract]
public class Cell : ObjectInstance
{
    [DataMember]
    public int cellId;

    public Cell(ScriptEngine  engine) : base(engine)
    {
    }
}

But I still get error. How to make action return only my fields of class serialized, and not get into parent classes?


Solution

  • You want to serialize the Cell class only, not its parent class, right? The solution is: create a custom JSON converter. Here is the code:

    Cell.cs

    [JsonConverter(typeof(CellJsonConverter))]
    public class Cell : Parent
    {
        public int CellId { get; set; }
        public string Name { get; set; }
    
        public Cell(int id) : base(id)
        {
            CellId = id;
            Name = "This is a name";
        }
    }
    

    CellJsonConverter.cs

    public class CellJsonConverter : JsonConverter
    {
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            var cell = (Cell) value;
    
            writer.WriteStartObject();
    
            writer.WritePropertyName("cellId");
            serializer.Serialize(writer, cell.CellId);
    
            writer.WritePropertyName("name");
            serializer.Serialize(writer, cell.Name);
    
            writer.WriteEndObject();
        }
    
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }
    
        public override bool CanConvert(Type objectType)
        {
            return objectType == typeof(Cell);
        }
    }
    

    When you call your API, you will get: {"cellId":10,"name":"This is a name"}.

    JsonConverter is from Newtonsoft.Json.

    Feel free to ask if there's something unclear to you :)