0

I'm trying to serialize a c# object to json to post to an external rest api.

The description to on property in my object was "LineItems is a list of LineItem"

So based on that, in C# i'd simply do this:

public List<LineItem> lineItems { get; set; }

public class LineItem
{
    public string dealerProductCode { get; set; }
    public string description { get; set; }
    public string quantity { get; set; }
    public string amount { get; set; }
}

Which would serialize into json like so:

{
        //other properties etc

       "lineItems":[
          {
             "dealerProductCode":"asdf",
             "description":"asdf",
             "quantity":"1",
             "amount":"100"
          }
       ]
    }

However, they give two examples, one in xml and one in json.

json:

{
    //other properties etc

   "lineItems":{
      "lineItem":[
         {
            "dealerProductCode":"asdf",
            "description":"asdf",
            "quantity":"1",
            "amount":"100"
         }
      ]
   }
}

To me, this looks like... - An object called lineItems - That contains an array called lineItem - The first item in that array is a lineItem object

In the xml example it seems to make a lot more sense:

<lineItems>
    <!--1 or more repetitions:-->
    <lineItem>
        <dealerProductCode>asdf</dealerProductCode>
        <description>asdf</description>
        <quantity>1</quantity>
        <amount>1</amount>
    </lineItem>
</lineItems> 

How can I craft my C# to produce the json output they have in their example?

mejobloggs
  • 7,937
  • 6
  • 32
  • 39
  • 2
    Side comment, you are right. Their JSON example is counter-intuitive. – DPac Feb 09 '16 at 21:43
  • I'm not sure how to do the example you want, but for me it makes sense the way they are doing it: First, you get the variable name (`lineItems`) and then, before the array, you need a way to send the type of the items (`lineItem`). Maybe it looks confusing, but it's functional – Lucas Rodriguez Feb 09 '16 at 21:47
  • See http://stackoverflow.com/a/16295052/1841212 – VisualBean Feb 09 '16 at 21:52
  • 1
    Here is a nice tool for going from Json to c#. It may require a few tweaks but it works as a good starting point. http://json2csharp.com/ – Brandon Johnson Feb 09 '16 at 21:53

2 Answers2

3

If you'll serialize an instance of Data class, you'll obtain the json from the example.

public class LineItem
{
    public string dealerProductCode { get; set; }
    public string description { get; set; }
    public string quantity { get; set; }
    public string amount { get; set; }
}

public class LineItemContainer
{
 public List<LineItem> lineItem{get;set;}
}

public class Data
{
  public LineItemContainer lineItems {get;set;}
}
Ion Sapoval
  • 635
  • 5
  • 8
0

I have ran into a similar problem before.

So, using the answer here, and JSON.NET serializer,

This can be achieved by defining custom JsonConverter and overriding the name.

It will work for all IEnumerable objects.

First decorate the IEnumerable object with the following annotation:

[JsonConverter(typeof(JSONSettings.AssociativeArraysConverter<LineItemFieldNameResolver>))] 
public List<LineItem> lineItems { get; set; }

Here is the custom implementation,

   public class LineItemFieldNameResolver : IAssociateFieldNameResolver
        {
            public string ResolveFieldName(object i_Object)
            {
                var item = (i_Object as LineItem);
                return "lineitem";
            }
        }

        public class AssociativeArraysConverter<T> : JsonConverter
            where T : IAssociateFieldNameResolver, new()
        {
            private readonly T _mFieldNameResolver;

            public AssociativeArraysConverter()
            {
                _mFieldNameResolver = new T();
            }

            public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
                JsonSerializer serializer)
            {
                throw new NotImplementedException(
                    "Unnecessary because CanRead is false. The type will skip the converter.");
            }

            public override bool CanRead
            {
                get { return false; }
            }

            public override bool CanConvert(Type objectType)
            {
                return typeof(IEnumerable).IsAssignableFrom(objectType) &&
                       !typeof(string).IsAssignableFrom(objectType);
            }

            public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
            {
                var collectionObj = value as IEnumerable;

                writer.WriteStartObject();

                foreach (var currObj in collectionObj)
                {
                    writer.WritePropertyName(_mFieldNameResolver.ResolveFieldName(currObj));
                    serializer.Serialize(writer, currObj);
                }

                writer.WriteEndObject();
            }
        }

        public interface IAssociateFieldNameResolver
        {
            string ResolveFieldName(object i_Object);
        }

I hope this helps. :)

mojorisinify
  • 377
  • 5
  • 22