1

For this class

class Customer {
  public string FirstName {get; set;}
  public string LastName {get; set;}
}

I have collection

List<Customer> customers

When returning to browser client

return new JsonResult(new
{
                data = customers
});

The client get

{"data":[{"firstName":"Johny","lastName":"Johnson"}]}

Is there some way to get

{"data":[{"Johny","Johnson"}]}

without doing foreach like

var output = new List<string[]>();
foreach (var r in customers)
{
     output.Add(new string[] {
          r.FirstName,
          r.LastName
     });
}

?

6
  • I'm not sure why you'd want to do that? What if you had more than 1 customer? Odd indices would be first names and even indices would be last names? It seems like this would make deserialization more difficult. Commented Aug 1, 2018 at 15:40
  • @itsme86 I am using jquery datatable library and by default this is presumed format, but because my table contains a lot of columns i want to avoid manually mapping object to an array. Commented Aug 1, 2018 at 15:43
  • So is your objection that you're having to type out the properties you want to extract into columns? How would the JSON formatter know which properties go into which column numbers? Or are you wanting a way to generalize mapping properties into arrays with a given set of column mappings? Commented Aug 1, 2018 at 15:47
  • 1
    @itsme86 is right, the only way to achieve what you are asking is having another function that does Reflection on your Type and returns only the Values without their corresponding PropertyNames then deserializing that. Commented Aug 1, 2018 at 15:47
  • thank you i will use the foreach. The datatable plugin probably map the array to the table based on value position. For example value of customer[3][2] will be in 3rd row and 2nd column. Commented Aug 1, 2018 at 15:53

2 Answers 2

3

You could add another property in the Customer object,

public string[] FullName {get { return new string[]{FirstName, LastName}; } } 

Decorate your Firstname and LastName properties with [JsonIgnore] so they don't get serialized.

Final product would look like so

public class Customer{

    [JsonIgnore]
    public string FirstName{get;set;}
    [JsonIgnore]
    public string LastName{get;set;}
    [JsonProperty("data")]
    public string[] FullName {get { return new string[]{FirstName, LastName}; } } 

    public Customer(string FirstName, string LastName){
        this.FirstName = FirstName;
        this.LastName = LastName;
    }
}

public static void Main(string[] args)
{
    Customer c = new Customer("Adrian", "i6");

    Console.Write(JsonConvert.SerializeObject(c));
}

This of course won't return exactly the desired result, if you wanted to completely remove the property you'll have to override the JsonWrite method inside JsonConverter however that would cause the JSON to be invalid of course as the JSON object requires a key:value property.

DotNetFiddle runnable of the above.

Sign up to request clarification or add additional context in comments.

Comments

1

If you want some sort of "automatically derive a table from an array of JSON objects" functionality that's general across any data type, the algorithm would be to:

  1. Iterate over the array, collecting newly-encountered property names into a list as you go into column names. This is the only way to get all property names since it may not be guaranteed that all objects have the same properties in JSON.
  2. Create a list for each object in the list
  3. Map each object's property value into the list index of the column corresponding to the property name

This will give you two output artifacts: the column listings and the values by index. If you are safe assuming that the first object has the same properties as all the other objects in the Array, then you can avoid iterating over the entire collection for the first step. This is untested, but hopefully you get the gist.

using System.Collections.Generic;
using Newtonsoft.Json.Linq;

// ...

var payload = JObject.Parse(rawJson);
var dataArray = payload["data"] as JArray;
var firstItem = dataArray[0] as JObject;
var columns = firstItem.Properties().Select(prop => prop.Name).ToList();
var rows = (
    from obj as JObject in dataArray
    select columns.Select(col => obj[col]).ToList()
).ToList();

3 Comments

I have underlined the obj property, it said that type or namespace could not be found ?! Also i changed the payload to var payload = (JObject)JToken.FromObject(customers); because i do have object first, i want to generate the json after.
Is customers the List<Customer>? If so, you'll need to convert it to a JArray (dataArray in the case of the sample)
I tried JArray.Parse(JsonConvert.SerializeObject(customers)); but it was the same error.. but because there are other issues with the mapping, i will stick with the foreach as the simplest solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.