Deserialising JSON and child object to List<Class> - c#

I've checked out a few questions on StackOverflow but can't find a method that works for me.
I'm essentially trying to deserialise the following JSON into a list of my "suppressedContact" class, but I can't get it to work.
The JSON looks like this:
[
{
"suppressedContact": {
"id": 23,
"email": "nelson.redeker#example.com",
"optInType": "Unknown",
"emailType": "PlainText",
"dataFields": null,
"status": "Unsubscribed"
},
"dateRemoved": "2015-09-18T15:26:25.2612537Z",
"reason": "Unsubscribed"
},
{
"suppressedContact": {
"id": 25,
"email": "terry.mccarthy#example.com",
"optInType": "VerifiedDouble",
"emailType": "Html",
"dataFields": null,
"status": "Unsubscribed"
},
"dateRemoved": "2015-02-24T13:06:42.933Z",
"reason": "Unsubscribed"
},
]
The class I am trying to deserialise into looks like this:
public class SuppressedRoot
{
public Suppressedcontact suppressedContact { get; set; }
public DateTime dateRemoved { get; set; }
public string reason { get; set; }
}
public class Suppressedcontact
{
public int id { get; set; }
public string email { get; set; }
public string optInType { get; set; }
public string emailType { get; set; }
public object dataFields { get; set; }
public string status { get; set; }
}
I'm using this piece of code to attempt to accomplish this:
List<Suppressedcontact> unsubscribedContacts = JsonConvert.DeserializeObject<List<Suppressedcontact>>(jsonResponse);
This however does not work.
Any help in this would be appreciated, I'm trying to get to a stage where I can loop through all of the returned contacts and extract the email addresses.

Try replacing
List<Suppressedcontact> unsubscribedContacts = JsonConvert.DeserializeObject<List<Supporesscontact>>(jsonResponse);
with
List<SuppressedRoot> unsubscribedContacts = JsonConvert.DeserializeObject<List<SuppressedRoot>>(jsonResponse);

Related

The fields that are given to the settings appear in the subclasses when serializing the object

I have classes like this.
public class Activity
{
public Guid Id { get; set }
public string Name { get; set; }
public Firm RelatedFirm { get; set; }
public string Email { get; set; }
public string Notes { get; set; }
}
public class Firm
{
public Guid Id { get; set }
public string Title { get; set; }
public string Email { get; set; }
public string Notes { get; set; }
}
After capturing the activity list, I'm sending them to a function to serialize. Within this function, serialize operation is performed according to certain parameters. One of these parameters is the fields in which I want the response to return. I want to return the Id, Name, RelatedFirm, Email and Notes fields for the activity and I want only the Id field to return to the Firm. The fields that I want to return to within the activity turn to me if they are in the firm.
This is my response;
{
"Id": "9294bc10-d8e1-4590-9703-75b773110d1c",
"Email": "q#q.com",
"RelatedFirm": {
"Id": "ebbe560b-f75d-4daf-9500-89a10487e51f",
"Email": "x#x.com",
"Notes": "87654323ıuyt43"
},
"Notes": null
}
This is also the answer I want to come;
{
"Id": "9294bc10-d8e1-4590-9703-75b773110d1c",
"Email": "q#q.com",
"RelatedFirm": {
"Id": "ebbe560b-f75d-4daf-9500-89a10487e51f"
},
"Notes": null
}
Is there any way I can stop this?

How do I configure services when I bind an array of objects?

I have a json string attached to the VCAP_SERVICES environment variable that looks like this:
{
"redislabs": [
{
"credentials": {
"host": "redis-1756.pcfredissb2.com",
"ip_list": [
"10.999.46.999"
],
"password": "cz(2u",
"port": 1756
},
"syslog_drain_url": null,
"volume_mounts": [],
"label": "redislabs",
"provider": null,
"plan": "simple-redis",
"name": "sdsredis2",
"tags": [
"redislabs"
]
},
{
"credentials": {
"host": "redis-13610.pcfredis.com",
"ip_list": [
"10.999.46.9999"
],
"password": "n-C*",
"port": 13610
},
"syslog_drain_url": null,
"volume_mounts": [],
"label": "redislabs",
"provider": null,
"plan": "simple-redis",
"name": "sdsredis",
"tags": [
"redislabs"
]
}
]
}
In ConfigureServices in Startup.cs, when I run Configuration.GetSection("redislabs").AsEnumerable() I get something that looks like this:
I have a few options classes that looks like this:
public class RedisLabs
{
public RedisLab[] redislabs { get; set; }
}
public class RedisLab
{
public Credentials credentials { get; set; }
public object syslog_drain_url { get; set; }
public object[] volume_mounts { get; set; }
public string label { get; set; }
public object provider { get; set; }
public string plan { get; set; }
public string name { get; set; }
public string[] tags { get; set; }
}
public class Credentials
{
public string host { get; set; }
public string[] ip_list { get; set; }
public string password { get; set; }
public int port { get; set; }
}
My question is how the heck do I perform the binding on something like this? Is binding an array of objects even possible?
I've tried:
var redislabs = new List<RedisLab>();
Configuration.GetSection("redislabs").Bind(redislabs);
and
services.Configure<RedisLabs>(Configuration);
and a few other methods. Nothing seems to work.
Halp, plz.
Given your json file and classes this should work (binding top level section to instance of a class that that holds the array):
var redisLabs = new RedisLabs();
Configuration.Bind(redisLabs);
This also works:
services.Configure<RedisLabs>(Configuration);
...
var rlOptions = app.ApplicationServices.GetRequiredService<IOptions<RedisLabs>>();
var redisLabs = rlOptions.Value;

Json Desearialization C# URL

I have this problem:
I'm consuming a JSON from backend which contains this:
"results": [{
"id": "3bc895f3-2439-4db8-8015-ddf82841c26b",
"code": "test",
"urlImagePromotion": "http://mmblob.blob.core.windows.net/img/img_02a479e2_4b41_4c34_bb34_afda77dbad9e.png"
}]
When i deserialize to my class, the attribute urlImagePromotion is allways null.
var response = JsonConvert.DeserializeObject<MultiResultResponse<TestClass>>(result);
public class MultiResultResponse<T>
{
public IEnumerable<T> Results { get; set; }
}
My TestClass:
public Guid? Id { get; set; }
public string Code { get; set; }
[JsonProperty("urlImagePromotion")]
public string UrlImagePromotion { get; set; }
Maybe its allways null because that string has special characters?
How can i get the correct value?
Thanks you

AJAX POST Complex JSON to MVC4 Controller

I have a complex JSON object that I'd like to pass to a MVC4 Controller route.
{
"name": "Test",
"description": "Description",
"questions": [
{
"id": "1",
"type": "1",
"text": "123",
"answers": [
{
"answer": "123",
"prerequisite": 0
},
{
"answer": "123",
"prerequisite": 0
}
],
"children": [
{
"id": "2",
"type": "2",
"text": "234",
"answers": [
{
"answer": "234",
"prerequisite": 0
},
{
"answer": "234",
"prerequisite": 0
}
],
"children": []
}
]
}
]
I have these ViewModels defined:
public class FormDataTransformContainer
{
public string name { get; set; }
public string description { get; set; }
public QuestionDataTransformContainer[] questions;
}
public class QuestionDataTransformContainer {
public int type { get; set; }
public string text { get; set; }
public AnswerDataTransformContainer[] answers { get; set; }
public QuestionDataTransformContainer[] children { get; set; }
}
public class AnswerDataTransformContainer {
public string answer { get; set; }
public int prerequisite { get; set; }
}
And this is the route I'm hitting:
[HttpPost]
public ActionResult Create(FormDataTransformContainer formData)
{
Currently, the name and description property on FormDataTransformContainer are set, but the questions array is null. I hoped that the Data Binding would figure it out, but I assume the tree nature of the data structure is a little complex for it. If I'm correct what is the best solution to this?
questions should be a property, not a field. I'd also change from arrays to IList<> (assuming your serialization library handles that well), because that's probably closer to what it should be, and lets you use a more generic interface instead of a specific implementation.
public class FormDataTransformContainer
{
public string name { get; set; }
public string description { get; set; }
public IList<QuestionDataTransformContainer> questions { get; set; }
}
public class QuestionDataTransformContainer {
public int type { get; set; }
public string text { get; set; }
public IList<AnswerDataTransformContainer> answers { get; set; }
public IList<QuestionDataTransformContainer> children { get; set; }
}
public class AnswerDataTransformContainer {
public string answer { get; set; }
public int prerequisite { get; set; }
}
I've tested this structure with Json.net (MVC4's default, I believe), and it works.
As #robert-harvey said, you should utilize libraries like JSON.NET that are already available to do the heavy lifting for you.
Pulled from the JSON.NET API docs:
If you create a string json that holds your json, you can read from it with new JsonTextReader(new StringReader(json))
I a similar problem, solved with the following code:
public class ExtendedController : Controller
{
public T TryCreateModelFromJson<T>(string requestFormKey)
{
if (!this.Request.Form.AllKeys.Contains(requestFormKey))
{
throw new ArgumentException("Request form doesn't contain provided key.");
}
return
JsonConvert.DeserializeObject<T>(
this.Request.Form[requestFormKey]);
}
}
And usage:
[HttpPost]
[ActionName("EditAjax")]
public ActionResult EditAjaxPOST()
{
try
{
var viewModel =
this.TryCreateModelFromJson<MyModel>(
"viewModel");
this.EditFromModel(viewModel);
return
this.JsonResponse(
this.T("Model updated successfuly."),
true);
}
catch (Exception ex)
{
this.Logger.Error(ex, "Error while updating model.");
return this.JsonResponse(this.T("Error"), false);
}
}
Called from JS:
function saveViewModel() {
$.post(
'#Url.Action("EditAjax")',
{
__RequestVerificationToken: '#Html.AntiForgeryTokenValueOrchard()',
viewModel: ko.mapping.toJSON(viewModel)
},
function (data) {
// response
});
}
Used additional library for deserializing/serializing JSON: http://www.nuget.org/packages/Newtonsoft.Json

Parsing nested JSON objects with JSON.NET

My JSON feed has nested objects like this:
{
"id": 1765116,
"name": "StrozeR",
"birth": "2009-08-12",
"avatar": "http:\/\/static.erepublik.com\/uploads\/avatars\/Citizens\/2009\/08\/12\/f19db99e9baddad73981d214a6e576ef_100x100.jpg",
"online": true,
"alive": true,
"ban": null,
"level": 61,
"experience": 183920,
"strength": 25779.42,
"rank": {
"points": 133687587,
"level": 63,
"image": "http:\/\/www.erepublik.com\/images\/modules\/ranks\/god_of_war_1.png",
"name": "God of War*"
},
"elite_citizen": false,
"national_rank": 6,
"residence": {
"country": {
"id": 81,
"name": "Republic of China (Taiwan)",
"code": "TW"
},
"region": {
"id": 484,
"name": "Hokkaido"
}
}
}
and my object classes are like this:
class Citizen
{
public class Rank
{
public int points { get; set; }
public int level { get; set; }
public string image { get; set; }
public string name { get; set; }
}
public class RootObject
{
public int id { get; set; }
public string name { get; set; }
public string avatar { get; set; }
public bool online { get; set; }
public bool alive { get; set; }
public string ban { get; set; }
public string birth { get; set; }
public int level { get; set; }
public int experience { get; set; }
public double strength { get; set; }
public List<Rank> rank { get; set; }
}
}
I try to parse my JSON data with following code
private async void getJSON()
{
var http = new HttpClient();
http.MaxResponseContentBufferSize = Int32.MaxValue;
var response = await http.GetStringAsync(uri);
var rootObject = JsonConvert.DeserializeObject<Citizen.RootObject>(response);
uriTB.Text = rootObject.name;
responseDebug.Text = response;
}
but I get the following error:
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[Erepublik.Citizen+Rank]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
I can't even parse the value in the main object. Anyway to fix this? and how can I parse a value inside of a nested object? for example: "points" in "rank"
Like the error message says, your rank property in the .NET class is a List<Rank>, but in your JSON it's just a nested object, not an array. Change it to just a Rank instead of a List<Rank>.
Arrays in JSON (or any Javascript, really) are enclosed in []. The {} characters specify a single object. The CLR type has to roughly match the JSON type in order to deserialize. Object to object, array to array.

Categories