How to add a boolean property to a JSON token - c#

I have some JSON which represents settings for an application. A simplified example is shown below:
{
"data": {
"app_settings": {
"jbofmngeodhmdlnicmlnfhjmmbdbcokh": {
"title": "app 1",
"description": "desc 1",
"custom_app_setting_stored_below": "asd",
"cust1": 3,
"cust2": false
},
"esghmzlnxcfpnrkbokmvgtjmcaknysdb": {
"title": "app 2",
"description": "desc 2",
"custom_app_setting_stored_below": "asd",
"cust8": 12,
"cust10": "11/25/2013",
"cust11": "nothing",
"cust12": true,
"cust13": 3
}
}
}
}
The application can have extensions (represented in the settings by the long random strings of letters), and each extension can have its own custom settings beneath it.
I can manually blacklist an extension by adding a "blacklist" property for an extension and setting it to true. This will prevent the extension from being loaded by the application.
Here's an example of a blacklisted extension:
"jbofmngeodhmdlnicmlnfhjmmbdbcokh": {
"title": "app 1",
"description": "desc 1",
"custom_app_setting_stored_below": "asd",
"cust1": 3,
"cust2": false,
"icons": {
"128": "text21456.gif",
"16": "text21456.gif",
"48": "text21456.gif"
},
"plugins": [
{
"path": "plugins/ApiPlugin.dll",
"public": true
},
{
"path": "plugins/mp.dll",
"public": true
},
{
"path": "plugins/Plugin.dll",
"public": true
}
],
"blacklist": true
}
Now I want to be able to blacklist an extension programmatically.
In C#, I'm searching for a specific extension like this:
var data = json["data"];
var app_settings = data["app_settings"];
var a = app_settings.Children().ToList();
foreach (var b in a)
{
if (b.ToString().ToLower().Contains("extensionname"))
{
JToken ext = b;
// need to add blacklist property here
}
}
So for example, if the search matches, I might have something like this in ext:
"jbofmngeodhmdlnicmlnfhjmmbdbcokh": {
"custom_extension_property_1": "value 1",
"custom_extension_property_2": "value 2"
}
How do I add a "blacklist" boolean property in those extension settings so it will look like this?
"jbofmngeodhmdlnicmlnfhjmmbdbcokh": {
"custom_extension_property_1": "value 1",
"custom_extension_property_2": "value 2",
"blacklist": true
}
I don't think this will work:
bool blacklist = true;
ext.AddAfterSelf(blacklist);
or this:
someobject o = new someobject() {
blacklist = true;
};
ext.AddAfterSelf(o);
What am I missing?

From your question it looks like you're trying to find a particular extension by its title, and then add a "blacklist" property to that extension's settings if the title is found. You can do that like this:
string extensionNameToBlacklist = "app 1";
var data = json["data"];
var app_settings = data["app_settings"];
foreach (JProperty extensionProperty in app_settings)
{
JObject extensionObject = (JObject)extensionProperty.Value;
if ((string)extensionObject["title"] == extensionNameToBlacklist)
{
extensionObject.Add("blacklist", true);
}
}
Fiddle: https://dotnetfiddle.net/tESgmB
I think the part you were missing is that JToken is just a base class for more specific token classes like JObject and JProperty. Sometimes you have to cast the JToken to be able to access methods and properties that are specific to that class, like the Add method on JObject. (If you have a token and you don't know what kind it is, you can check its Type property to find out.)

Related

Get Value From JSON File stored in Azure Storage Using C#

I have JSON file in Azure Storage which I am reading using C#. In that JSON file there is anode called SQLViewDifinition and that node I have SQL which I need to fetch.
I have read the file into a string and converted that string in JObject. I have the JSON now but is finding it difficult to read that particular node. Tried with JToken and Jproperty. But could not crack it.
JSON file looks like this:
{
"jsonSchemaSemanticVersion": "1.4.0",
"imports": [
{
"corpusPath": "cdm:/foundations.cdm.json"
},
{
"corpusPath": "localCdm:/foundations.cdm.json"
}
],
"definitions": [
{
"entityName": "METCredManCollectionGroupEntity",
"exhibitsTraits": [
{
"traitReference": "is.CDM.entityVersion",
"arguments": [
{
"name": "versionNumber",
"value": "1.0.0"
}
]
},
{
"traitReference": "has.sqlViewDefinition",
"arguments": [
{
"name": "sqlViewDefinition",
"value": "CREATE VIEW [DBO].[METCREDMANCOLLECTIONGROUPENTITY] AS SELECT T1.COLLECTIONGROUPID AS COLLECTIONGROUPID, T1.DESCRIPTION AS DESCRIPTION, T1.RECID AS CREDMANCOLLECTIONGROUPTABLERECID, T1.DATAAREAID AS CREDMANCOLLECTIONGROUPTABLEDATAAREAID, T1.RECVERSION AS RECVERSION, T1.PARTITION AS PARTITION, T1.RECID AS RECID FROM CREDMANCOLLECTIONGROUPTABLE T1"
}
]
},
{
"traitReference": "has.backingElements",
"arguments": [
{
"name": "backingElements",
"value": "CredManCollectionGroupTable"
}
]
}
],
"hasAttributes": [
{
"name": "CollectionGroupId",
"dataType": "CredManCollectionGroupId",
"isNullable": true,
"displayName": "Collection group",
"maximumLength": 10
},
{
"name": "Description",
"dataType": "Description",
"isNullable": true,
"displayName": "Description",
"maximumLength": 60
},
{
"name": "CredmanCollectionGroupTableRecId",
"dataType": "other",
"isNullable": true,
"displayName": "Record-ID"
},
{
"name": "CredmanCollectionGroupTableDataAreaId",
"dataType": "other",
"isNullable": true,
"displayName": "Company"
}
],
"displayName": "MET Collection groups (Shared)"
},
{
"explanation": "Collection group",
"dataTypeName": "CredManCollectionGroupId",
"extendsDataType": "SysGroup"
},
{
"explanation": "Group",
"dataTypeName": "SysGroup",
"extendsDataType": "string"
},
{
"explanation": "Description",
"dataTypeName": "Description",
"extendsDataType": "string"
}
]
}
I need to find sqlViewDefinition from this file.
So far I can read the JSON in a JSON object. But could not find a way to get the view definition.
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
using Nancy.Json;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
public class FindFiles
{
// Main Method with int return type
static int Main(String[] args)
{
Console.WriteLine("Buid SQL");
// for successful execution of code
return X("FILE_NAME");
}
public static int X(string fileName)
{
//connection string
string storageAccount_connectionString = "CONNECTION_STRING";
// Retrieve storage account from connection string.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(storageAccount_connectionString);
// Create the blob client.
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
// Retrieve reference to a previously created container.
CloudBlobContainer container = blobClient.GetContainerReference("CONTAINER");
//The specified container does not exist
try
{
//root directory
CloudBlobDirectory dira = container.GetDirectoryReference(string.Empty);
//true for all sub directories else false
var rootDirFolders = dira.ListBlobsSegmentedAsync(true, BlobListingDetails.Metadata, null, null, null, null).Result;
foreach (var blob in rootDirFolders.Results)
{
if (blob.Uri.OriginalString.Contains(fileName, StringComparison.OrdinalIgnoreCase) && blob.Uri.OriginalString.Contains(".cdm.json", StringComparison.OrdinalIgnoreCase))
{
Console.WriteLine("Blob: " + blob.Uri.OriginalString);
if (blob.GetType() == typeof(CloudBlockBlob))
{
CloudBlockBlob b = (CloudBlockBlob)blob;
string jsonText = b.DownloadTextAsync().Result;
Dictionary<string, object> json_Dictionary = (new JavaScriptSerializer()).Deserialize<Dictionary<string, object>>(jsonText.ToString());
JObject json = JObject.Parse(jsonText);
}
}
}
}
catch (Exception e)
{
// Block of code to handle errors
Console.WriteLine("Error", e);
}
return 1;
}
}
As you are using .NET 6 and because the structure is always the same, the easiest way to deserialize is to mimic the structure of the JSON in C# classes. You can then easily deserialize the JSON into objects and access the properties of the objects instead of "brachiating" through dynamic data.
In order to get the classes, you can use Visual Studio's Paste Special function (Edit -> Paste special -> Paste JSON as classes). This generates the classes for you (you can adjust the classes if you don't need parts of them or change the casing of the property names; also you can use attributes to customize the serialization).
Afterwards, it is easy to parse the JSON into an object, e.g. (I've put your sample JSON into the jsonContent variable):
var obj = System.Text.Json.JsonSerializer.Deserialize<Rootobject>(jsonContent);
Because it still is a complex structure, getting to the SQL needs a bit of code:
Console.WriteLine(obj
.definitions[0]
.exhibitsTraits
.Where(x => x.traitReference == "has.sqlViewDefinition")
.First().arguments.Where(x => x.name == "sqlViewDefinition")
.First().value);
Finally, the above code writes the following output:
CREATE VIEW [DBO].[METCREDMANCOLLECTIONGROUPENTITY] AS SELECT T1.COLLECTIONGROUPID AS COLLECTIONGROUPID, T1.DESCRIPTION AS DESCRIPTION, T1.RECID AS CREDMANCOLLECTIONGROUPTABLERECID, T1.DATAAREAID AS CREDMANCOLLECTIONGROUPTABLEDATAAREAID, T1.RECVERSION AS RECVERSION, T1.PARTITION AS PARTITION, T1.RECID AS RECID FROM CREDMANCOLLECTIONGROUPTABLE T1
You can use this documentation to get familiar with JSON handling in .NET 6.

Redefining recipient role on template on an envelope to envelope basis?

I want to reuse a DocuSign template for multiple recipients in the same envelope. The template is rather simple; it has a few signing and date signed blocks.
The recipients will have different routing orders. From what I've seen, my API request needs to have the Routing Order and Role Name match the DocuSign template. If the role name and routing order don't match, I end up with an empty role (which has all of the signing blocks) on the envelope. I've also tried "merge roles on draft." The empty role will be merged into the second recipient, but I lose all of the template's signing blocks for that recipient.
Is there a way to use a template but modify the definition of the template recipient role? Ideally, I'd like to use the exact same template but change the routing order of that role for the second recipient. I'd like to avoid creating new templates in DocuSign since I could end up with many combinations.
I'd like to accomplish (UPDATE):
I want to use the same template two times in a single envelope. Each recipient will be assigned to an individual copy of the template. The final envelope should have two recipients, two documents, and each recipient will only have access and visibility to their document.
The issue is that the template's role defines the routing order. The routing order of "1" is applicable for the first recipient using the template, but the second recipient needs a routing order of "2." (The template's role expects a routing order of "1" in all cases, but I want that value to be a "2" for the second recipient.)
Example Template Information:
Template Name (for example purposes): Test Template #1
Role Name: Applicant 1
Routing Order: 1 (if I don't define the routing order, DocuSign treats it as a "1" anyways)
Example Request:
EnvelopeDefinition envDef = new EnvelopeDefinition();
var signer1 = new Signer()
{
RecipientId = "1",
Name = "First User 1",
RoleName = "Applicant 1",
Email = "fakeemail1#email.com",
RoutingOrder = "1"
};
var signer2 = new Signer()
{
RecipientId = "2",
Name = "First User 2",
RoleName = "Applicant 1",
Email = "fakeemail2#email.com",
RoutingOrder = "2"
};
envDef.CompositeTemplates = new List<CompositeTemplate>();
var composite1 = new CompositeTemplate()
{
ServerTemplates = new List<ServerTemplate>()
{
new ServerTemplate("1", "Test Template #1 TEMPLATE_ID_GUID_HERE")
},
InlineTemplates = new List<InlineTemplate>()
{
new InlineTemplate()
{
Sequence = "1",
Recipients = new Recipients()
{
Signers = new List<Signer>()
{
signer1
}
}
}
}
};
var composite2 = new CompositeTemplate()
{
ServerTemplates = new List<ServerTemplate>()
{
new ServerTemplate("2", "Test Template #1 TEMPLATE_ID_GUID_HERE")
},
InlineTemplates = new List<InlineTemplate>()
{
new InlineTemplate()
{
Sequence = "2",
Recipients = new Recipients()
{
Signers = new List<Signer>()
{
signer2
}
}
}
}
};
envDef.CompositeTemplates.Add(composite1);
envDef.CompositeTemplates.Add(composite2);
envDef.EnforceSignerVisibility = "true";
// Code to send envelope
Note: Also, I'm using composite templates since our envelopes will likely have various combinations of templates and uploaded documents.
Thank you!
This can be achieved by passing a query parameter - change_routing_order=true while creating an envelope. So endpoint for creating envelope will be
https://{{EnvironmentVal}}/restapi/v2/accounts/{{AccountIdVal}}/envelopes?change_routing_order=true
and body of the request will be
Req Body:
where same templateId - 076d9062-cfc7-408b-a47f-88c4b74af62b is used with same RoleName but diff routing order and diff Signer details
{
"compositeTemplates": [
{
"inlineTemplates": [
{
"recipients": {
"signers": [
{
"email": "email+internal#gmail.com",
"name": "John Doe",
"recipientId": "1",
"roleName": "Signer1",
"routingOrder": "1"
}
]
},
"sequence": "2"
}
],
"serverTemplates": [
{
"sequence": "1",
"templateId": "076d9062-cfc7-408b-a47f-88c4b74af62b"
}
]
},
{
"inlineTemplates": [
{
"recipients": {
"signers": [
{
"email": "email+internal2#gmail.com",
"name": "John Doe2",
"recipientId": "2",
"roleName": "Signer1",
"routingOrder": "2"
}
]
},
"sequence": "2"
}
],
"serverTemplates": [
{
"sequence": "1",
"templateId": "076d9062-cfc7-408b-a47f-88c4b74af62b"
}
]
}
],
"status": "sent"
}

Deserializing Json String into multiple Object types

I have a Json String that I get from a web service; it has a list of collections, each collection represents an object, for example:
[ // Root List
[ // First Collection : Team Object
{
"id": 1,
"team_name": "Equipe Saidi",
"is_active": true,
"last_localisation_date": "2015-05-06T13:33:15+02:00"
},
{
"id": 3,
"team_name": "Equipe Kamal",
"is_active": true,
"last_localisation_date": "2015-05-06T09:22:15+02:00"
}
],
[// Second Collection : user Object
{
"id": 1,
"login": "khalil",
"mobile_password": "####",
"first_name": "Abdelali",
"last_name": "KHALIL",
"email": "KHALIL#gmail.com",
"role": "DR",
"is_active": true,
"charge": false
},
{
"id": 2,
"login": "ilhami",
"mobile_password": "####",
"first_name": "Abdellah",
"last_name": "ILHAMI",
"email": "ILHAMI#gmail.com",
"role": "DR",
"is_active": true,
"charge": false
}
]
]
My actual code (not working of course ):
public async Task TeamsAndMobileUsers()
{
string data = "";
IList<User> MobileUsersList = new List<User>();
IList<Team> TeamsList = new List<Team>();
try
{
data = await GetResponse(PATH + TEAMS_USERS_URL);
TeamsList = JsonConvert.DeserializeObject<List<Team>>(data);
MobileUsersList = JsonConvert.DeserializeObject<List<User>>(data);
// Inserting
await SetAchievedActions(TeamsList);
}
catch (Exception e) {
_errors.Add(e.Message);
}
}
I use Json.net and C#. I can't find a solution, I've read that I should use JsonReader and set its SupportMultipleContent property to true but I don't know how to implement that solution.
As #YeldarKurmangaliyev already said, your json has two different objects, I think you can do something like this:
var j = JArray.Parse(data);
TeamsList = JsonConvert.DeserializeObject<List<Team>>(j[1].ToString());
MobileUsersList = JsonConvert.DeserializeObject<List<User>>(j[2].ToString());
have you tried http://json2csharp.com/ to generate contract classes for that json? also, first and last parenthesis gives a not valid JSON
You need to create 4 classes
1st class TeamObject : Variable(id,team_name,is_active,last_localisation_date)
2nd class UserObject : Variable (id, login,mobile_password,first_name, last_name , email, role,is_active,charge)
3rd class RootList: Variable ( arraylist<TeamObject> obj, arraylist<UserObject > obj2)
4th class RootClass : Variable(arraylist<RootList> obj)
Gson gson=new Gson();
RootClass dtomodel = gson.fromJson(data , RootClass .class);
This parsing done using Gson Library

Square Connect API Item Creation syntax

I am trying to post a new item creation to a test store via C#, but I'm not sure how the syntax should read. Square Connect API requires at least one variation for new item creation, but I'm not sure how to add that to the JSON body. Here is what I have, but I'm not sure how to complete it.
var client = new RestSharp.RestClient();
var post = new RestRequest("https://connect.squareup.com/v1/me/items", Method.POST);
post.RequestFormat = DataFormat.Json;
post.AddHeader("Authorization", String.Format("Bearer {0}", testtoken));
post.AddBody(new { name = testname, variations = ???? });
This code works, but returns a response of an item must include at least one variation. I realize that, but do not know how to write it, or if it is even possible.
I am not opposed to going a different route.
Edited to add a sample request body from the Square documentation:
{
"name": "Milkshake",
"description": "It's better than yours",
"visibility": "PRIVATE",
"category_id": "36ac7016-3a4e-4934-81f1-9057ac613f2y",
"variations": [
{
"name": "Small",
"pricing_type": "FIXED_PRICING",
"price_money": {
"currency_code": "USD",
"amount": 400
},
"sku": "123"
}
]
}
Something like this should serialize to JSON in the correct format:
post.AddBody(new {
name = testname,
variations = new object[] {
new {
name = "Small",
pricing_type = "FIXED_PRICING",
price_money = new {
currency_code = "USD",
amount = 400
}
}
},
sku = "123"
});

How to obtain values in JSON in C#?

i have json string as :
{
"data": [
{
"id": "100000045402409_310121622373595",
"from": {
"name": "Ritesh Ranjan",
"id": "100000045402409"
},
"message": "greatttttttttttttt ab jaooooooooo",
"picture": "http://external.ak.fbcdn.net/safe_image.php?d=AQAGY5rsr5AeM5PI&w=90&h=90&url=http\u00253A\u00252F\u00252Fwww.ndtv.com\u00252Fnews\u00252Fimages\u00252Ftopstory_thumbnail\u00252FChidambaram_2G_120.jpg",
"link": "http://www.ndtv.com/article/india/2g-scam-chidambaram-verdict-expected-shortly-huge-implications-for-govt-173168",
"name": "2G scam: Chidambaram verdict expected shortly, huge implications for govt",
"caption": "www.ndtv.com",
"description": "A Delhi court handling the 2G spectrum allocation scam trial is likely to decide today whether Union Home Minister P Chidambaram should be made a co-accused in the case for allegedly allowing former Telecom Minister A Raja to gift mobile network licenses and scarce second-generation or 2G spectrum a...",
"icon": "http://static.ak.fbcdn.net/rsrc.php/v1/yD/r/aS8ecmYRys0.gif",
"type": "link",
"application": {
"name": "Links",
"id": "2309869772"
},
"created_time": "2012-02-04T11:02:22+0000",
"updated_time": "2012-02-04T11:02:22+0000"
},
{
"id": "100003303253347_132959650157476",
"from": {
"name": "Suman Dey",
"id": "100003303253347"
},
"message": "Check out this article I was reading on biNu. 2G verdict: Chidambaram off the hook, government exhales",
"type": "status",
"application": {
"name": "biNu",
"canvas_name": "binuapp",
"namespace": "binuapp",
"id": "378628085054"
},
"created_time": "2012-02-04T10:54:19+0000",
"updated_time": "2012-02-04T10:54:19+0000"
},
.....
//Continued...
Now i want to parse it using c#
i have used :
WebClient client = new WebClient();
string Json = client.DownloadString("https://graph.facebook.com/search?q=2g+verdict+Chidambaram&type=post");
System.IO.StreamWriter SW = new System.IO.StreamWriter(JsonDestFile);
SW.WriteLine(Json);
System.IO.StreamWriter SW1 = new System.IO.StreamWriter(ValuesDestFile);
JObject o = JObject.Parse(Json);
var postTitles = from p in o["data"].Children()["from"]
select p["name"].Values<string>();
foreach (var item in postTitles)
{
SW1.WriteLine(item);
}
SW1.WriteLine(name);
But i am not able to get any name values at all.
Its giving me error : Cannot access child value on Newtonsoft.Json.Linq.JValue.
Please suggest me how can i parse the above json for values of id, name, id (from one) , message
I got it working...
var postTitles = from p in JO["data"].Children()
select new
{
Names = (string)p["from"]["name"],
Msg = (string)p["message"],
};
Using this LINQ i can access the required data.
I haven't used the LINQ to JSON API, but if you don't insist on using it you can simply create a class that models the data in your JSON payload and then use the following method:
Newtonsoft.Json.JsonConvert.DeserializeObject<YourDataModelClass>()
you need to deseriralise the json string as shown below
public static T Deserialise<T>(string json)
{
using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(json)))
{
var serialiser = new DataContractJsonSerializer(typeof(T));
return (T)serialiser.ReadObject(ms);
}
}
Return type is you class
public class MyData
{
public string id { get; set;}
public string name{ get; set;}
public string message{ get; set;}
}
you can check full details : Parse JSON in C#
This also will work
JObject hh = JObject.Parse(jsonstring);
string name = (string)hh["Name"];

Categories