Converting to correctly formatted JSON - json

I've been tasked will calling an API, that needs to take a JSON payload as its request.. An example format of the JSON is as follows:
{
"method":"methodname",
"in":[
{
"account":"acme",
"context":"abc123"
},
"content",
{
"mSearchText":"chocolate",
"mItemDataIDs":[
"Entry:ID",
"Entry:EntryRef",
"Entry:CategoryID"
]
}
]
}
I am using JSON.NET (Newstonsoft) to construct my JSON from .net objects.
The issue I am facing is correctly constructing the "in" section..
It appears to be an array of objects, but only the second item has a title ("content",{.....})..
The closest I can get is:
{
"method": "methodname",
"in":[
{
"account": "PANDO",
"context": "sdfsd22342"
},
{
"mSearchText":"chocolate",
"mItemDataIDs":[
"Entry:ID",
"Entry:EntryRef",
"Entry:CategoryID"
]
}
]
}
Which is identical apart from "content", is missing:
My code so far is:
public class Payload
{
public string method { get; set; }
[JsonProperty("in")]
public List<object> Items { get; set; }
}
public class AccountDetails
{
public string account { get; set; }
public string context { get; set; }
}
[JsonObject(Title = "content")]
public class Content
{
public string mSearchText { get; set; }
public string[] mItemDataIDs { get; set; }
}
Payload payload = new Payload();
payload.method = "methodname";
payload.Items = new List<object>();
payload.Items.Add(new AccountDetails
{
account = "acme",
context = "abc123"
});
Content conent = new Content
{
mSearchText = "chocolate",
mItemDataIDs = new string[] { "Entry:ID", "Entry:EntryRef", "Entry:CategoryID" }
};
payload.Items.Add(conent);
string jsonObject = JsonConvert.SerializeObject(payload, Formatting.Indented);
Any suggestions on what I can do?

Related

Deserialize complex json in C#

I have this json and need to parse the nested details. using Newtonsoft.Json for Deserializing but cant really parse this complex json.
{
"name": "John",
"email": "john#gmail.com",
"data": [
{
"company_name": "instagram",
"company_email": "abc#email.com",
"org": {
"org_name": "john-insta",
"org_dob": "1/1/1990",
}
},
{
"company_name": "google",
"company_email": "abc1#email.com",
"org": {
"org_name": "john-google",
"org_dob": "1/1/1990",
}
},
]
The number of entries in "data" may actually be varying dynamically, how do I parse the entries for company_name, company_email, org_name,org_dob.
What is the problem you are having? This seems fairly simple JSON array. Setup your classes like this.
public class MyClass
{
public string name { get; set; }
public string email { get; set; }
public List<DataClass> data { get; set; }
}
public class DataClass
{
public string company_name { get; set; }
public string company_email { get; set; }
public Org org { get; set; }
//Any other and all possible properties...
}
public class Org
{
public string org_name { get; set; }
public string org_dob { get; set; }
}
Then it can be parsed using Newtonsoft or similar using.
var test = JsonConvert.DeserializeObject<MyClass>(json);
This method also has an overload where you can pass settings to ignore nulls.
var test = JsonConvert.DeserializeObject<MyClass>(json,
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });

deserialize dataset in xamarin forms

How can you decrypt/ deserialize dataset. here is what i am getting from the web service. I am new to xamarin forms. Thanks in advance. i tried this json2csharp.com to convert, but got an error because it can convert datatable to csharp but not datasets.
[
[
{
"bit_HasError":false,
"vchar_ErrorMsg":""
}
],
[
{
"int_SurveyQuestionID":1,
"vchar_Description":"we",
"vchar_Instruction":"Question Instruction",
"int_AnswerType":1
},
{
"int_SurveyQuestionID":5,
"vchar_Description":"this is the question 2",
"vchar_Instruction":null,
"int_AnswerType":2
}
],
[
{
"int_SurveyQuestionID":1,
"vchar_Option":"option1"
},
{
"int_SurveyQuestionID":5,
"vchar_Option":"answer1"
},
{
"int_SurveyQuestionID":5,
"vchar_Option":"answer2"
},
{
"int_SurveyQuestionID":5,
"vchar_Option":"answer3"
},
{
"int_SurveyQuestionID":1,
"vchar_Option":"optionn2"
}
]
]
Using https://app.quicktype.io/ it is quite easy to get started, just copy paste your json in there, here is the result:
// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:
//
// using QuickType;
//
// var prject = Prject.FromJson(jsonString);
namespace QuickType
{
using System;
using System.Collections.Generic;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
public partial class Prject
{
[JsonProperty("bit_HasError", NullValueHandling = NullValueHandling.Ignore)]
public bool? BitHasError { get; set; }
[JsonProperty("vchar_ErrorMsg", NullValueHandling = NullValueHandling.Ignore)]
public string VcharErrorMsg { get; set; }
[JsonProperty("int_SurveyQuestionID", NullValueHandling = NullValueHandling.Ignore)]
public long? IntSurveyQuestionId { get; set; }
[JsonProperty("vchar_Description", NullValueHandling = NullValueHandling.Ignore)]
public string VcharDescription { get; set; }
[JsonProperty("vchar_Instruction")]
public string VcharInstruction { get; set; }
[JsonProperty("int_AnswerType", NullValueHandling = NullValueHandling.Ignore)]
public long? IntAnswerType { get; set; }
[JsonProperty("vchar_Option", NullValueHandling = NullValueHandling.Ignore)]
public string VcharOption { get; set; }
}
public partial class Prject
{
public static List<List<Prject>> FromJson(string json) => JsonConvert.DeserializeObject<List<List<Prject>>>(json, QuickType.Converter.Settings);
}
public static class Serialize
{
public static string ToJson(this List<List<Prject>> self) => JsonConvert.SerializeObject(self, QuickType.Converter.Settings);
}
internal static class Converter
{
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
{
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
DateParseHandling = DateParseHandling.None,
Converters = {
new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
},
};
}
}
P.S.: Please note that you have to modify the class names.

JSON. A reference deserializes to null

I am using Newtonsoft.json. I can't understand result of a deserialization. Bulletin.PageList is being filled ok. But Page of Question which is referencing to element of PageList is always null. In the JsonSerializerSettings I specified PreserveReferencesHandling.All but it didn't help. Could you help to resolve the problem of null of Page? Thank you
JSON structure:
"Bulletins": [
{
"$id": "46b5efa80fe644d7bd525e2c30f5df8a",
"$type": "Bulletin",
"JSONNETTYPE": "Bulletin",
"PagesList": [
{
"id": "4ed13d727cd144d1acf1e0c9bc273245",
"JSONNETTYPE": "PageView",
"Number": 1,
"Id": "1a2b8ed4249948e194b396c46a5d1eeb",
"UiId": "4ed13d727cd144d1acf1e0c9bc273245"
}
],
"AgendaQuestions": [
{
"$id": "eceb6fe6c74a40d59f0673b76bd6dbb3",
"$type": "QSimple",
"Page": {
"$ref": "46b5efa80fe644d7bd525e2c30f5df8a#PagesList.0"
}
}
]
}]
C# structure:
public class Bulletin
{
public Bulletin()
{
}
public string Dbid { get; set; }
public List<PageView> PagesList;
public List<Question> AgendaQuestions;
}
public abstract class Question
{
protected Question(int number, string customNumberLabel = null)
{
Number = number;
CustomNumberLabel = customNumberLabel;
}
public int Number { get; set; }
public string CustomNumberLabel { get; set; }
public PageView Page { get; set; }
}
public class PageView
{
public int Number { get; set; }
public string Id { get; set; }
public int BulletinNumber { get; set; }
public PageView()
{
}
}
var settings = new JsonSerializerSettings
{ PreserveReferencesHandling = PreserveReferencesHandling.All
}
I was using dojox.json.ref library. If I set __id for Page, references to elements of PagesList will become direct, not complex (like 46b5efa80fe644d7bd525e2c30f5df8a#PagesList.0), and Page is filled.

How to use a POCO object to access an array of options in the appsettings.json file (ASP.NET 5)

I am using ASP.NET 5 and I want to use POCO classes to access my appsettings.json file. This file looks like this:
{
"Data": {
"ErpSystemConnection": {
"ConnectionString": "[myConnectionString]"
}
},
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Verbose",
"System": "Information",
"Microsoft": "Information"
}
},
"GoogleAnalytics": {
"Account": [
{
"Name": "AccountName",
"ServiceAccountEmailAddress": "someEmail#someaccount.iam.gserviceaccount.com",
"KeyFileName": "key1.p12",
"Password": "notasecret"
},
{
"Name": "AnotherAccount",
"ServiceAccountEmailAddress": "anotherEmailAccount#someotheraccount.iam.gserviceaccount.com",
"KeyFileName": "key2.p12",
"Password": "notasecret"
}
],
"KeyFilePath": "/googleApis/"
}
}
The 'GoogleAnalytics' key contains an array of accounts that I wish to be able to access in a collection either as a list or an array.
I created a POCO to represent this key that contains a corresponding collection of 'Account' objects:
public class GoogleAnalytics
{
public Account[] Account { get; set; } = new Account[1];
public string KeyFilePath { get; set; }
public GoogleAnalytics()
{
}
}
And the 'Account' object:
public class Account
{
private const string _applicationName = #"Storefront Analytics";
private X509Certificate2 _certificate;
private ServiceAccountCredential _credential;
private AnalyticsService _service;
#region |--Properties--|
public string Name { get; set; }
public string Password { get; set; }
public string ServiceAccountEmailAddress { get; set; }
public string KeyFileName { get; set; }
public string KeyFilePath { get; set; }
public string KeyFileFullPath
{
get
{
return $"{KeyFilePath}{KeyFileName}";
}
}
public X509Certificate2 Certificate
{
get
{
if(_certificate == null)
{
ConfigureInstance();
}
return _certificate;
}
set
{
_certificate = value;
}
}
public ServiceAccountCredential Credential
{
get
{
if (_credential == null)
{
ConfigureInstance();
}
return _credential;
}
set
{
_credential = value;
}
}
public AnalyticsService Service
{
get
{
if (_service == null)
{
ConfigureInstance();
}
return _service;
}
set
{
_service = value;
}
}
#endregion
#region |--Constructors--|
public Account()
{
}
public Account(string password, string keyFileName,
string keyFilePath,
string serviceAccountEmailAddress, string accountName)
{
//TODO: Validate parameters
Password = password;
KeyFileName = keyFileName;
KeyFilePath = keyFilePath;
ServiceAccountEmailAddress = serviceAccountEmailAddress;
Name = accountName;
}
#endregion
private void ConfigureInstance()
{
Certificate = new X509Certificate2(KeyFileFullPath, Password, X509KeyStorageFlags.Exportable);
Credential = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(ServiceAccountEmailAddress)
{
Scopes = new[] { AnalyticsService.Scope.Analytics }
});
Service = new AnalyticsService(new BaseClientService.Initializer()
{
HttpClientInitializer = Credential,
ApplicationName = _applicationName
});
}
}
My Controller:
public class GoogleAnalyticsController : Controller
{
#region |--Properties--|
[FromServices]
private IGoogleAnalyticsRepository _repo { get; set; }
#endregion
public GoogleAnalyticsController(IOptions<GoogleAnalytics> options)
{
var temp = options.Value;
}
}
The 'KeyFilePath' property is properly set in the IOptions instance.
The problem I am having is that the Account array contains null references - none of the accounts are being instantiated. I wondering if I am doing this wrong, or the Options Model doesn't support this type of behavior at this time?
Update in response to Shaun Luttin's answer
I implemented the changes listing in Shaun Luttin's answer. There seems to have been an additional problem. For whatever reason, all of the Account instances' properties were null until I simplified the class as follows:
public class Account
{
public string Name { get; set; }
public string Password { get; set; }
public string ServiceAccountEmailAddress { get; set; }
public string KeyFileName { get; set; }
public string KeyFilePath { get; set; }
}
Short Answer
I wondering if I am doing this wrong, or the Options Model doesn't support this type of behavior at this time?
You are doing one thing wrong. The Options Model does support arrays. You need NOT to initialize your array property with an array of size [1].
public Account[] Account { get; set; } = new Account[1]; // wrong
public Account[] Account { get; set; } // right
Demo
Here is a sample, just for you, that you can find here on GitHub.
MyOptions.cs
namespace OptionsExample
{
public class MyObj
{
public string Name { get; set; }
}
public class MyOptions
{
public string Option1 { get; set; }
public string[] Option2 { get; set; }
public MyObj[] MyObj { get; set; }
}
}
Startup.cs
namespace OptionsExample
{
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Hosting;
using Microsoft.AspNet.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.OptionsModel;
using System.Linq;
public class Startup
{
public IConfigurationRoot Config { get; set; }
public Startup(IHostingEnvironment env)
{
Config = new ConfigurationBuilder().AddJsonFile("myoptions.json").Build();
}
public void ConfigureServices(IServiceCollection services)
{
services.AddOptions();
services.Configure<MyOptions>(Config);
}
public void Configure(IApplicationBuilder app,
IOptions<MyOptions> opts)
{
app.Run(async (context) =>
{
var message = string.Join(",", opts.Value.MyObj.Select(a => a.Name));
await context.Response.WriteAsync(message);
});
}
}
}
myoptions.json
{
"option1": "option1val",
"option2": [
"option2val1",
"option2val2",
"option2val3"
],
"MyObj": [
{
"Name": "MyObj1"
},
{
"Name": "MyObj2"
}
]
}
project.json dependencies
"dependencies": {
"Microsoft.AspNet.Mvc": "6.0.0-rc1-final",
"Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final",
"Microsoft.Extensions.Configuration.Json": "1.0.0-rc1-final"
}
Output

Insert JSON formatted string into JSON structure

I have a question about inserting a json formatted string into a json structure and having the final version be a combined JSON formatted string that can be serialized into a JSON structure. I am using the newtonsofts Json.NET
I have the following JSON structure:
public class ResponseJson
{
[JsonProperty(PropertyName = "header")]
public ResponseHeader responseHeader { get; set; }
[JsonProperty(PropertyName = "results")]
public string responseResults { get; set; }
}
public class ResponseHeader
{
[JsonProperty(PropertyName = "name")]
public string name { get; set; }
[JsonProperty(PropertyName = "version")]
public string version { get; set; }
}
In the code, I do the following:
ResponseJson responseJson = new ResponseJson();
responseJson.responseHeader = new ResponseHeader()
{
name = A_NAME,
version = A_VERSION
};
responseJson.responseResults = resultJson;
return JsonConvert.SerializeObject(responseJson, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
resultJson is a properly formatted JSON string (in this case, an array of objects, but could be anything JSON formatted). Right now, if i execute the code, I get the following (which is expected, since "results" is declared as a string):
{
"header":
{
"name":"abcd",
"version":"1.0"
},
"results":
"[{\"data\":{\"level\":\"100\"},\"code\":{\"value\":\"JBC\",\"type\":\"ev\"},\"time\":{\"start\":\"20\",\"end\":\"101\"}}]"
}
what I do need as an output is:
{
"header":
{
"name":"abcd",
"version":"1.0"
},
"results":
[
{
"data":
{
"level":"100"
},
"code":
{
"value":"JBC",
"type":"ev"
},
"time":
{
"start":"20",
"end":"101"
}
}
]
}
While you don't explain how you create your resultJson variable, it's implied from your code that you are double-serializing your results: you compute an array of "result" classes, serialize them to a JSON string, store the string in your ResponseJson class, and them serialize that in turn. The embedded JSON string then gets escaped as per the JSON standard, which is what you are seeing.
You need to avoid double-serializing your data, for instance by using the following data model:
public class ResponseJson<T>
{
[JsonProperty(PropertyName = "header")]
public ResponseHeader responseHeader { get; set; }
[JsonProperty(PropertyName = "results")]
public T responseResults { get; set; }
}
public static class ResponseJson
{
public static ResponseJson<T> Create<T>(T responseResults, ResponseHeader responseHeader)
{
return new ResponseJson<T> { responseResults = responseResults, responseHeader = responseHeader };
}
}
public class ResponseHeader
{
[JsonProperty(PropertyName = "name")]
public string name { get; set; }
[JsonProperty(PropertyName = "version")]
public string version { get; set; }
}
Then you would do:
var results = GetResults(); // Get your result data
var responseJson = ResponseJson.Create(results, new ResponseHeader()
{
name = A_NAME,
version = A_VERSION
});
return JsonConvert.SerializeObject(responseJson, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
If for whatever reason you must embed a previously serialized JSON string as JSON rather than as a string literal, you'll need to re-parse it back to a JToken:
string resultJson = GetResultJson(); // Get result json string.
var responseJson = ResponseJson.Create(JToken.Parse(resultJson), new ResponseHeader()
{
name = A_NAME,
version = A_VERSION
});
return JsonConvert.SerializeObject(responseJson, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
Json.NET will include the JToken in your outer JSON as nested JSON rather than as a string literal.