1
votes

I have an observable collection that contains a list of products that is binded to ListView.

However I want to export this Observable Collection as a JSON file AND only specific entries so I can submit it through the API.

For example.

The full observable collection contains

  • Product ID
  • Product Name
  • Product Price
  • Product Qty

But I want to extract the JSON file to only:

  • Product ID
  • Product Qty

Here's my code:

public static ObservableCollection<FBProduct> fbproducts = new ObservableCollection<FBProduct>();

Here's my JSON deserialiser

shoppingcartjson = JsonConvert.SerializeObject(ShoppingCart.fbproducts);

How can I only extract only ProductID and ProductQTY from that ObservableCollection like so:

"line_items": [{"product_id":79631,"quantity":1}],
2

2 Answers

2
votes

It's simple in your FBProduct class use the JsonIgnore attribute!

For instance:

 public class FBProduct
 {    
    [JsonIgnore]
    public double Name  { get; set; } 
    .
    .

Also, add the following using statement:

using Newtonsoft.Json;

Good luck!

Feel free to get back if you have questions.

2
votes

If you want to always ignore a property when serialising your FBProduct, then go ahead and use FreakyAli's answer. I'll give a quick explainer as to how to ignore properties only sometimes.


Sometimes you want to ignore some properties, while other times you want the full class without ignoring any properties. But by placing a [JsonIgnore] attribute on a property you will ignore it always, which isn't great. So instead, Newtonsoft offers a way to ignore properties conditionally, using what they call a contract resolver. You can implement your own contract resolvers to be able to programmatically ignore properties sometimes (as well as do everything else you could using their attributes).
Here is how you would go about implementing a contract resolver that conditionally ignores some properties:

public class IgnorePropertyContractResolver : DefaultContractResolver
{
    // Holds our information for which properties to ignore on which types
    private readonly Dictionary<Type, HashSet<string>> _ignores;

    public IgnorePropertyContractResolver()
    {
        _ignores = new Dictionary<Type, HashSet<string>>();
    }

    public void IgnoreProperty(Type type, params string[] propertyNames)
    {
        // If we don't know the type to ignore properties on, initialize the HashSet
        if (_ignores.ContainsKey(type))
            _ignores[type] = new HashSet<string>();
 
        foreach (var prop in propertyNames)
            _ignores[type].Add(prop);
    }

    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        // Create the property as normal
        var property = base.CreateProperty(member, memberSerialization);

        // If we're ignoring the property
        if (IsIgnored(property.DeclaringType, property.PropertyName))
        {
            // Don't serialize and ignore
            property.ShouldSerialize = i => false;
            property.Ignored = true;
        }

        return property;
    }


    private bool IsIgnored(Type type, string propertyName)
    {
        // If we're not ignoring any property on the type, return false
        if (!_ignores.ContainsKey(type))
            return false;

        // If we are ignoring some properties on the type, return if we're ignoring the given property
        return _ignores[type].Contains(propertyName);
    }
}

We then use this custom contract resolver as follwing:

var fbProduct = new FBProduct();
var resolver = new IgnorePropertyContractResolver();
resolver.IgnoreProperty(typeof(FBProduct),
    nameof(FBProduct.ProductID),
    nameof(FBProduct.Name),
    nameof(FBProduct.Price),
    nameof(FBProduct.Qty)
);

var serialized = JsonConvert.SerializeObject(
    fbProduct,
    Formatting.None, // You can choose any formatting you want
    new JsonSerializerSettings 
    {
        ContractResolver = resolver
    }
);