1

json is passed from browser using POST method to ASP.NET MVC4 application controller in server. It contains properites from which 3 are arrays of 0.. 20 elements (in code below all of them have only 1 element). How to parse this json in C# ? I tried controller with signature

public JsonResult RegisterSales(Sale mysale)

but mysale properties are not assigned.

passed json:

{ "id":"sale1",
  "sale_date":"2013-11-10 19:20:44"
  "taxes":[{"id":"km20pr","name":"20%","rate":0.2}],
  "products":[{"id":"prod1",
            "sale_id":"sale1",
            "register_id":"register1",
            "quantity":"1.00000"}],

  "payments":[{"id":"payment1",
            "sale_id":"sale1",
            "register_id":"register1",
           "amount": 0
      }]
 }

It should parsed to C# structure something like

public class Sale
        {
            public string id;
            public DateTime sale_date;
            public Tax[] taxes;
            public Product[] products;
            public Payment[] payments;
        }

public class Tax
        {
            public string id, name;
            public decimal rate;
        }

public class Product
        {
            public string id, sale_id, register_id;
            public decimal quantity;
        }


public class Payment
        {
            public string id, sale_id, register_id;
            public decimal amount;
        }
Andrus
  • 26,339
  • 60
  • 204
  • 378
  • 1
    How do you post the JSON to MVC? (the code is what is really important). e.g. AJAX => what is the data you are sending? – Gecko Nov 10 '13 at 21:33
  • http POST request body contains text - json which is published in question. I added `{get; set;}` to every property in every class in question and it looks like properties are populated with data. Is this best solution? – Andrus Nov 10 '13 at 21:44

3 Answers3

1

Use NewtonSoft JSON Deserialize, like so:

class School
{
    public string student;
    public object[] data;
}

School datum = JsonConvert.Deserialize<School>(jsonStr);
//Do stuff with datum...

Enjoy.

RealityDysfunction
  • 2,609
  • 3
  • 26
  • 53
0

You need to post data with correct content type. In this case it's application/json. MVC chooses correct binding mode based on the content type used to send data to a server.

Siim
  • 436
  • 1
  • 4
  • 6
  • Http header in post contains `Content-Type:application/json; charset=UTF-8` so it looks like it is correct. I added `{get; set;}` to every property and it looks like now json is parsed properly. Is this best solution ? – Andrus Nov 10 '13 at 21:50
  • Sorry, I missed that you were using fields. MVC model binder only looks for settable fields when doing the binding. If you want to use NewtonSoft's serializer, you can swap out MVC's default JSON serializer [see here for a guideline](http://www.dalsoft.co.uk/blog/index.php/2012/01/10/asp-net-mvc-3-improved-jsonvalueproviderfactory-using-json-net/) – Siim Nov 10 '13 at 21:54
  • I tried to use it but date is still returned in Microsoft format. I posted it in http://stackoverflow.com/questions/20035870/how-to-return-json-date-from-mvc4-controller-in-iso-format – Andrus Nov 17 '13 at 20:39
0

The best thing to do is to have the same name for the json as for your accepting variable "mysale". Example:

"mysale": { "id":"sale1",
  "sale_date":"2013-11-10 19:20:44"
  "taxes":[{"id":"km20pr","name":"20%","rate":0.2}],
  "products":[{"id":"prod1",
            "sale_id":"sale1",
            "register_id":"register1",
            "quantity":"1.00000"}],

  "payments":[{"id":"payment1",
            "sale_id":"sale1",
            "register_id":"register1",
           "amount": 0
      }]
 }

You can do this by adding the name in the AJAX call by so:

$.ajax({
   ...,
   ...,
   data: JSON.stringify({mysale:data}),
   ...,
   ...
});

Now it will accept your JSON.

The reason for this is that the JSON posted will be viewed as a post value, and just like with a normal form you can catch this value by its name.

So to answer your question: adding {get;set;} is not the best way to go.

Gecko
  • 1,333
  • 1
  • 14
  • 26