0

I have following scenario where I am getting OrderBase obstract class from ThirdParty library. And I have to inherit this abstract class into my model Order to get base attributes. Only below base attributes are required to be return as part of response.

  1. Id
  2. Name
  3. OrderHistory

But actually it return all the base attributes as part of response due to inheritance. So is there any way by which we can restrict no of base attributes to be pass in the result without introduction of intermediate model(s) and mappings.

Code Sample- Third Party:

[DataContract]
[Serializable]
public abstract class OrderBase
{
    public OrderBase(DatabaseObject obj)
    {
        this.Id = obj.Id;
        this.Name = obj.Name;
        this.Description = obj.Description;
        this.ClosingDate = obj.ClosingDate;
        this.Price = obj.Price;
    }

    [DataMember]
    public string Id { get; set; }

    [DataMember]
    public string Name { get; set; }

    [DataMember]
    public string Description { get; set; }

    [DataMember]
    public decimal Price { get; set; }

    [DataMember]
    public string ClosingDate { get; set; }
}

public class DatabaseObject
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public decimal Price { get; set; }
    public string ClosingDate { get; set; }
    public string OrderHistory { get; set; }
}

Model:

[DataContract]
[Serializable]
public class Order : OrderBase
{
    public Order(DatabaseObject dbObject)
        : base(dbObject)
    {
        this.OrderHistory = dbObject.OrderHistory;
    }

    [DataMember]
    public string OrderHistory { get; set; }
}

API Code:

public class OrderController : ApiController
{
        public Order GetOrder()
        {
            var dbObj = new DatabaseObject
            {
                Id = "O001",
                Name = "Masala Packets",
                ClosingDate = "01/02/2016",
                Description = "Payment Successful",
                OrderHistory = "",
                Price = 10000
            };

            var orderObj = new Order(dbObj);

            return orderObj;
        }
 }

Current JSON Result:

 {
      "OrderHistory": "",
      "Id": "O001",
      "Name": "Masala Packets",
      "Description": "Payment Successful",
      "Price": 10000.0,
      "ClosingDate": "01/02/2016"
    }

Expected JSON Result:

{
      "OrderHistory": "",
      "Id": "O001",
      "Name": "Masala Packets"     
}
Sumit Deshpande
  • 2,155
  • 2
  • 20
  • 36

2 Answers2

1

You're serializing your domain models directly. That may not be a good idea. It's better to create a view model to send your serialized data and you will have complete control of what to serialize as well as better separation of concerns. Something like an OrderDTO

public class OrderDTO {

    public string Id { get; set; }

    public string Name { get; set; }

    public string OrderHistory { get; set; }
}

In your web api method:

public class OrderController : ApiController
{
        public OrderDTO GetOrder()
        {
            // return an OrderDTO instead;
        }
}

Or you can use JsonIgnore property to exclude properties from serialization in case you want to expose your domain classes:

[DataContract]
[Serializable]
public abstract class OrderBase
{
    public OrderBase(DatabaseObject obj)
    {
        this.Id = obj.Id;
        this.Name = obj.Name;
        this.Description = obj.Description;
        this.ClosingDate = obj.ClosingDate;
        this.Price = obj.Price;
    }

    [DataMember]
    public string Id { get; set; }

    [DataMember]
    public string Name { get; set; }

    [DataMember]
    [JsonIgnore]
    public string Description { get; set; }

    [DataMember]
    [JsonIgnore]
    public decimal Price { get; set; }

    [DataMember]
    [JsonIgnore]
    public string ClosingDate { get; set; }
}
Khanh TO
  • 48,509
  • 13
  • 99
  • 115
  • Yes I want to do similar but with JsonIgnore it still populates all the attributes in response..Also even if it works it may cause the issue when another method where other attributes are required. – Sumit Deshpande Feb 27 '16 at 12:16
  • @Sumit Deshpande: looks like your `DatabaseObject` also contains these properties. If you want to exclude those properties also on your `DatabaseObject`, apply `JsonIgnore` on those fields too. But I'd recommend creating a DTO. – Khanh TO Feb 27 '16 at 12:18
  • Agree but with DTO approach we have to manually assign all the values right? if yes then actually i want to avoid that step as actual object is huge and re-mapping may take time...Please suggest. – Sumit Deshpande Feb 27 '16 at 12:24
  • DTO with AutoMapper is working perfectly fine...Thanks for your guidance. AutoMapper implementation I referred - http://www.codeproject.com/Articles/639618/CRUD-Opearations-using-AutoMapper-in-an-MVC-Applic – Sumit Deshpande Feb 27 '16 at 13:19
  • @Sumit Deshpande: glad to hear that. – Khanh TO Feb 27 '16 at 13:36
0

Use the [ScriptIgnore] attribute on the property you don't want to serialize as JSON.

If you don't want to do this in the parent class, you should shadow or overload the property in your child class and add the attribute there.

How to exclude property from Json Serialization

Community
  • 1
  • 1
Dave Bush
  • 2,382
  • 15
  • 12