I know it sounds basic but all answers around this question have been stupidly large and bulky code that does not allow the functionality i need. i need to parse this json array.
[
{
"label":"Cow (1)",
"value":3309
},
{
"label":"Cow (1)",
"value":14998
},
{
"label":"Cow (4)",
"value":20969
},
{
"label":"Cow (4)",
"value":20970
},
{
"label":"Cow (4)",
"value":20971
},
{
"label":"Cowardly Bandit",
"value":1886
},
{
"label":"Cow calf (1)",
"value":2310
},
{
"label":"Coward in armour (82)",
"value":5097
},
{
"label":"Coward with bow (105)",
"value":6049
},
{
"label":"Cow calf (1)",
"value":20979
},
{
"label":"Undead cow (4)",
"value":1691
},
{
"label":"Plague cow",
"value":1998
},
{
"label":"Plague cow",
"value":1999
},
{
"label":"Unicow (57)",
"value":5603
},
{
"label":"Zombie cow (1)",
"value":18597
},
{
"label":"Zombie cow (1)",
"value":20928
},
{
"label":"Super Cow (5)",
"value":21497
},
{
"label":"Dairy cow",
"value":22418
},
{
"label":"Armoured cow thing (62)",
"value":5986
},
{
"label":"Armoured cow thing (62)",
"value":6048
}
]
And when i try to access the data point inside the array it returns null, code:
Stream stream = client.OpenRead("http://services.runescape.com/m=itemdb_rs/bestiary/beastSearch.json?term=" + Input);
StreamReader reader = new StreamReader(stream);
jObject = JObject.Parse(reader.ReadToEnd());
stream.Close();
//put items into list view
// i is the number where the json object is in the array
var lvi = new ListViewItem(new string[] { (string)jObject[i]["label"], (string)jObject[i]["value"] });
I do not want to use classes
Found error in your code. Instead:
JObject.Parse(reader.ReadToEnd());
Write (JObject -> JArray):
string text = reader.ReadToEnd();
var jObject = JArray.Parse(text);
Also when write operation in 2 lines, you will see where the error: in reading from the stream or in serialization.
Not wanting to use classes is weird but not impossible.
var json = reader.ReadToEnd();
var objects = JsonConvert.DeserializeObject<dynamic[]>(json);
var lvi = new ListViewItem(new string[] { (string)objects[i].label, (string)objects[i].value });
Try my answer to this question :
public IEnumerable<MeItem> DeserializeListFromJson(string jsonArray)
{
return JsonConverter.DeserializeObject<List<JObject>>(jsonArray).Select( obj => DeserializeFromJson(obj) );
}
public MeItem DeserializeFromJson(string jsonString)
{
return JsonConvert.DeserializeObject<MeItem>(jsonString);
}
You can find necessary detailed informations in my answer for this question and this one
Edit:
If you do not want to use classes then you can just modify DeserializeFromJson() method into something like this :
public KeyValuePair<string, string> DeserializeFromJson(JObject obj)
{
return new KeyValuePair<string, string>(obj.SelectToken("label").Value<string>(), obj.SelectToken("value").Value<string>());
}
Which will require to modify DeserializeListFromJson() method into :
public IEnumerable<KeyValuePair<string,string>> DeserializeListFromJson(string jsonArray)
{
return JsonConverter.DeserializeObject<List<JObject>>(jsonArray).Select( obj => DeserializeFromJson(obj) );
}
Usage with your case :
Stream stream = client.OpenRead("http://services.runescape.com/m=itemdb_rs/bestiary/beastSearch.json?term=" + Input);
ListViewItem item = null;
using (StreamReader reader = new StreamReader(stream))
{
KeyValuePair<string, string> selected = DeserializeListFromJson(reader.ReadToEnd()).ElementAt(i);
item = new ListViewItem(new string[] { selected.Key, selected.Value });
}
Related
I am trying to search a json file with a string and then return a value from the same object as that string. This is a part of the json file:
[
"7c6b2f",
"EYZ",
"Australia",
1611990353,
1611990419,
144.8364,
-37.6611,
13114.02,
false,
50.42,
171.56,
null,
null,
null,
"5064",
true,
0
],
[
"7c6b0c",
"JST",
"New-Zealand",
1611990440,
1611990440,
148.4636,
-33.7973,
10668,
false,
248.2,
37.84,
-0.33,
null,
11170.92,
"1461",
false,
0
]
I want to have it so that if the user enters EYZ then the code will return Australia. I am currently setting the json file to a string but I am not sure how you would create objects to search in this scenario.
First of all, this is not a valid json file. You need to enclose it in an array element:
[
[
"xyz"
...
],
[
]
]
Once your object is valid, you can you the JSON.Net library to parse it in your code
// Here you'll have your value
string json = #"[
'Small',
'Medium',
'Large'
]";
JArray a = JArray.Parse(json);
And you can see How to access elements of a JArray (or iterate over them) how to iterate/access them.
JSON.Net
public static string Search(string input)
{
using (var sr = new StreamReader("your.json"))
{
var reader = new JsonTextReader(sr);
while (reader.Read())
{
if (reader.TokenType==JsonToken.String)
{
var value = reader.ReadAsString();
if (value == input)
{
return reader.ReadAsString();
}
}
}
}
return null;
}
SystemExtensions.Core
public static string Search(string input)
{
using (var sr = new StreamReader("your.json"))
{
var reader = JsonReader.CreateJson5(sr, 2048);
while (reader.Read())
{
if (reader.IsString)
{
var value = reader.GetString();
if (value == input)
{
if (reader.Read() && reader.IsString)
{
return reader.GetString();
}
}
}
}
}
return null;
}
How to create initial push into newly created Repository using VSTS Git API?
I have created a new repository.
using Microsoft.TeamFoundation.SourceControl.WebApi;
using Microsoft.VisualStudio.Services.WebApi;
using Microsoft.TeamFoundation.Core.WebApi
var accountUri = new Uri("https://mysite.visualstudio.com");
var personalAccessToken = "myaccesstoken";
var connection = new VssConnection(accountUri, new VssBasicCredential(string.Empty, personalAccessToken));
// Get a GitHttpClient to talk to the Git endpoints
var gitClient = connection.GetClient<GitHttpClient>();
var teamProject = projectClient.GetProject("MyProject", true, true).Result;
var repo = gitClient.CreateRepositoryAsync(new GitRepository
{
DefaultBranch = "refs/heads/master",
Name = "TestRepo",
ProjectReference = new TeamProjectReference
{
Id = teamProject.Id
}
}).Result;
The repo is successfully created. But why is the repo.DefaultBranch value is null?
Next step, I'd like to push my initial commit.
var newBranch = new GitRefUpdate
{
RepositoryId = repo.Id,
Name = $"refs/heads/master"
};
string newFileName = "README.md";
GitCommitRef newCommit = new GitCommitRef
{
Comment = "Initial commit",
Changes = new GitChange[]
{
new GitChange
{
ChangeType = VersionControlChangeType.Add,
Item = new GitItem { Path = $"/master/{newFileName}" },
NewContent = new ItemContent
{
Content = "# Thank you for using VSTS!",
ContentType = ItemContentType.RawText,
},
}
}
};
GitPush push = gitClient.CreatePushAsync(new GitPush
{
RefUpdates = new GitRefUpdate[] { newBranch },
Commits = new GitCommitRef[] { newCommit },
}, repo.Id).Result;
I got an error when calling CreatePushAsync:
VssServiceException: The combination of parameters is either not valid
or not complete. Parameter name: baseCommitId
Please help how to create initial commit properly.
You could use the rest api to achieve what you want. The rest api of creating an initial commit (create a new branch) is as below:
POST https://fabrikam.visualstudio.com/_apis/git/repositories/{repositoryId}/pushes?api-version=4.1
{
"refUpdates": [
{
"name": "refs/heads/master",
"oldObjectId": "0000000000000000000000000000000000000000"
}
],
"commits": [
{
"comment": "Initial commit.",
"changes": [
{
"changeType": "add",
"item": {
"path": "/readme.md"
},
"newContent": {
"content": "My first file!",
"contentType": "rawtext"
}
}
]
}
]
}
I am using .NET JSON parser and would like to serialize my config file so it is readable. So instead of:
{"blah":"v", "blah2":"v2"}
I would like something nicer like:
{
"blah":"v",
"blah2":"v2"
}
My code is something like this:
using System.Web.Script.Serialization;
var ser = new JavaScriptSerializer();
configSz = ser.Serialize(config);
using (var f = (TextWriter)File.CreateText(configFn))
{
f.WriteLine(configSz);
f.Close();
}
You are going to have a hard time accomplishing this with JavaScriptSerializer.
Try JSON.Net.
With minor modifications from JSON.Net example
using System;
using Newtonsoft.Json;
namespace JsonPrettyPrint
{
internal class Program
{
private static void Main(string[] args)
{
Product product = new Product
{
Name = "Apple",
Expiry = new DateTime(2008, 12, 28),
Price = 3.99M,
Sizes = new[] { "Small", "Medium", "Large" }
};
string json = JsonConvert.SerializeObject(product, Formatting.Indented);
Console.WriteLine(json);
Product deserializedProduct = JsonConvert.DeserializeObject<Product>(json);
}
}
internal class Product
{
public String[] Sizes { get; set; }
public decimal Price { get; set; }
public DateTime Expiry { get; set; }
public string Name { get; set; }
}
}
Results
{
"Sizes": [
"Small",
"Medium",
"Large"
],
"Price": 3.99,
"Expiry": "\/Date(1230447600000-0700)\/",
"Name": "Apple"
}
Documentation: Serialize an Object
A shorter sample code for Json.Net library
private static string FormatJson(string json)
{
dynamic parsedJson = JsonConvert.DeserializeObject(json);
return JsonConvert.SerializeObject(parsedJson, Formatting.Indented);
}
If you have a JSON string and want to "prettify" it, but don't want to serialise it to and from a known C# type then the following does the trick (using JSON.NET):
using System;
using System.IO;
using Newtonsoft.Json;
class JsonUtil
{
public static string JsonPrettify(string json)
{
using (var stringReader = new StringReader(json))
using (var stringWriter = new StringWriter())
{
var jsonReader = new JsonTextReader(stringReader);
var jsonWriter = new JsonTextWriter(stringWriter) { Formatting = Formatting.Indented };
jsonWriter.WriteToken(jsonReader);
return stringWriter.ToString();
}
}
}
Shortest version to prettify existing JSON: (edit: using JSON.net)
JToken.Parse("mystring").ToString()
Input:
{"menu": { "id": "file", "value": "File", "popup": { "menuitem": [ {"value": "New", "onclick": "CreateNewDoc()"}, {"value": "Open", "onclick": "OpenDoc()"}, {"value": "Close", "onclick": "CloseDoc()"} ] } }}
Output:
{
"menu": {
"id": "file",
"value": "File",
"popup": {
"menuitem": [
{
"value": "New",
"onclick": "CreateNewDoc()"
},
{
"value": "Open",
"onclick": "OpenDoc()"
},
{
"value": "Close",
"onclick": "CloseDoc()"
}
]
}
}
}
To pretty-print an object:
JToken.FromObject(myObject).ToString()
Oneliner using Newtonsoft.Json.Linq:
string prettyJson = JToken.Parse(uglyJsonString).ToString(Formatting.Indented);
Net Core App
var js = JsonSerializer.Serialize(obj, new JsonSerializerOptions {
WriteIndented = true
});
All this can be done in one simple line:
string jsonString = JsonConvert.SerializeObject(yourObject, Formatting.Indented);
Here is a solution using Microsoft's System.Text.Json library:
static string FormatJsonText(string jsonString)
{
using var doc = JsonDocument.Parse(
jsonString,
new JsonDocumentOptions
{
AllowTrailingCommas = true
}
);
MemoryStream memoryStream = new MemoryStream();
using (
var utf8JsonWriter = new Utf8JsonWriter(
memoryStream,
new JsonWriterOptions
{
Indented = true
}
)
)
{
doc.WriteTo(utf8JsonWriter);
}
return new System.Text.UTF8Encoding()
.GetString(memoryStream.ToArray());
}
You may use following standard method for getting formatted Json
JsonReaderWriterFactory.CreateJsonWriter(Stream stream, Encoding encoding, bool ownsStream, bool indent, string indentChars)
Only set "indent==true"
Try something like this
public readonly DataContractJsonSerializerSettings Settings =
new DataContractJsonSerializerSettings
{ UseSimpleDictionaryFormat = true };
public void Keep<TValue>(TValue item, string path)
{
try
{
using (var stream = File.Open(path, FileMode.Create))
{
//var currentCulture = Thread.CurrentThread.CurrentCulture;
//Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
try
{
using (var writer = JsonReaderWriterFactory.CreateJsonWriter(
stream, Encoding.UTF8, true, true, " "))
{
var serializer = new DataContractJsonSerializer(type, Settings);
serializer.WriteObject(writer, item);
writer.Flush();
}
}
catch (Exception exception)
{
Debug.WriteLine(exception.ToString());
}
finally
{
//Thread.CurrentThread.CurrentCulture = currentCulture;
}
}
}
catch (Exception exception)
{
Debug.WriteLine(exception.ToString());
}
}
Pay your attention to lines
var currentCulture = Thread.CurrentThread.CurrentCulture;
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
....
Thread.CurrentThread.CurrentCulture = currentCulture;
For some kinds of xml-serializers you should use InvariantCulture to avoid exception during deserialization on the computers with different Regional settings. For example, invalid format of double or DateTime sometimes cause them.
For deserializing
public TValue Revive<TValue>(string path, params object[] constructorArgs)
{
try
{
using (var stream = File.OpenRead(path))
{
//var currentCulture = Thread.CurrentThread.CurrentCulture;
//Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
try
{
var serializer = new DataContractJsonSerializer(type, Settings);
var item = (TValue) serializer.ReadObject(stream);
if (Equals(item, null)) throw new Exception();
return item;
}
catch (Exception exception)
{
Debug.WriteLine(exception.ToString());
return (TValue) Activator.CreateInstance(type, constructorArgs);
}
finally
{
//Thread.CurrentThread.CurrentCulture = currentCulture;
}
}
}
catch
{
return (TValue) Activator.CreateInstance(typeof (TValue), constructorArgs);
}
}
Thanks!
Using System.Text.Json set JsonSerializerOptions.WriteIndented = true:
JsonSerializerOptions options = new JsonSerializerOptions { WriteIndented = true };
string json = JsonSerializer.Serialize<Type>(object, options);
2023 Update
For those who ask how I get formatted JSON in .NET using C# and want to see how to use it right away and one-line lovers. Here are the indented JSON string one-line codes:
There are 2 well-known JSON formatter or parsers to serialize:
Newtonsoft Json.Net version:
using Newtonsoft.Json;
var jsonString = JsonConvert.SerializeObject(yourObj, Formatting.Indented);
.Net 7 version:
using System.Text.Json;
var jsonString = JsonSerializer.Serialize(yourObj, new JsonSerializerOptions { WriteIndented = true });
using System.Text.Json;
...
var parsedJson = JsonSerializer.Deserialize<ExpandoObject>(json);
var options = new JsonSerializerOptions() { WriteIndented = true };
return JsonSerializer.Serialize(parsedJson, options);
First I wanted to add comment under Duncan Smart post, but unfortunately I have not got enough reputation yet to leave comments. So I will try it here.
I just want to warn about side effects.
JsonTextReader internally parses json into typed JTokens and then serialises them back.
For example if your original JSON was
{ "double":0.00002, "date":"\/Date(1198908717056)\/"}
After prettify you get
{
"double":2E-05,
"date": "2007-12-29T06:11:57.056Z"
}
Of course both json string are equivalent and will deserialize to structurally equal objects, but if you need to preserve original string values, you need to take this into concideration
I have something very simple for this. You can put as input really any object to be converted into json with a format:
private static string GetJson<T> (T json)
{
return JsonConvert.SerializeObject(json, Formatting.Indented);
}
This worked for me. In case someone is looking for a VB.NET version.
#imports System
#imports System.IO
#imports Newtonsoft.Json
Public Shared Function JsonPrettify(ByVal json As String) As String
Using stringReader = New StringReader(json)
Using stringWriter = New StringWriter()
Dim jsonReader = New JsonTextReader(stringReader)
Dim jsonWriter = New JsonTextWriter(stringWriter) With {
.Formatting = Formatting.Indented
}
jsonWriter.WriteToken(jsonReader)
Return stringWriter.ToString()
End Using
End Using
End Function
.NET 5 has built in classes for handling JSON parsing, serialization, deserialization under System.Text.Json namespace. Below is an example of a serializer which converts a .NET object to a JSON string,
using System.Text.Json;
using System.Text.Json.Serialization;
private string ConvertJsonString(object obj)
{
JsonSerializerOptions options = new JsonSerializerOptions();
options.WriteIndented = true; //Pretty print using indent, white space, new line, etc.
options.NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals; //Allow NANs
string jsonString = JsonSerializer.Serialize(obj, options);
return jsonString;
}
Below code works for me:
JsonConvert.SerializeObject(JToken.Parse(yourobj.ToString()))
For UTF8 encoded JSON file using .NET Core 3.1, I was finally able to use JsonDocument based upon this information from Microsoft: https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-how-to#utf8jsonreader-utf8jsonwriter-and-jsondocument
string allLinesAsOneString = string.Empty;
string [] lines = File.ReadAllLines(filename, Encoding.UTF8);
foreach(var line in lines)
allLinesAsOneString += line;
JsonDocument jd = JsonDocument.Parse(Encoding.UTF8.GetBytes(allLinesAsOneString));
var writer = new Utf8JsonWriter(Console.OpenStandardOutput(), new JsonWriterOptions
{
Indented = true
});
JsonElement root = jd.RootElement;
if( root.ValueKind == JsonValueKind.Object )
{
writer.WriteStartObject();
}
foreach (var jp in root.EnumerateObject())
jp.WriteTo(writer);
writer.WriteEndObject();
writer.Flush();
I am using the official C# Mailjet SDK (https://github.com/mailjet/mailjet-apiv3-dotnet). Works fine so far.
But how do I add attachments?
I see
Mailjet.Client.Resources
has InlineAttachments and Attachments, but how do I use it?
This is the code snippet so far:
MailjetRequest request = new MailjetRequest { Resource = Send.Resource }
.Property(Send.FromEmail, emailOperatable.FromEmailaddress)
.Property(Send.FromName, emailOperatable.FromName)
.Property(Send.Subject, emailOperatable.Subject)
.Property(Send.TextPart, emailOperatable.TextBody)
.Property(Send.HtmlPart, emailOperatable.HtmlBody)
.Property(Send.Recipients, new JArray { new JObject { { "Email", emailOperatable.ContactEmailaddress }, { "Name", emailOperatable.CreateSendToName() } } });
Tried sth. like
request.Property(Send.Attachments, "path/to/file.zip");
But that does not work.
Update
Works like this:
.Property(Send.Attachments, new JArray { new JObject { { "Content-Type", "<content type>" }, { "Filename", "<file name>" }, { "content", "<base 64 encoded content>" } } });
It appears that the naming is a bit different, this worked for me in 2022 with the API v3
Mind the capitalization of some letters (or the lack thereof...)!
Note: content field is base64 encoded filedata.
.Property(
Send.Attachments,
new JArray {
new JObject {
{"Content-type", "text/plain"},
{"Filename", "test.txt"},
{"content", "VGhpcyBpcyB5b3VyIGF0dGFjaGVkIGZpbGUhISEK"}
}
}
)
According to their docs, the way to do it is:
MailjetClient client = new MailjetClient(Environment.GetEnvironmentVariable("MJ_APIKEY_PUBLIC"), Environment.GetEnvironmentVariable("MJ_APIKEY_PRIVATE"))
{
Version = ApiVersion.V3_1,
};
MailjetRequest request = new MailjetRequest
{
Resource = Send.Resource,
}
.Property(Send.Messages, new JArray {
new JObject {
{"From", new JObject {
{"Email", "pilot#mailjet.com"},
{"Name", "Mailjet Pilot"}
}},
{"To", new JArray {
new JObject {
{"Email", "passenger1#mailjet.com"},
{"Name", "passenger 1"}
}
}},
{"Subject", "Your email flight plan!"},
{"TextPart", "Dear passenger 1, welcome to Mailjet! May the delivery force be with you!"},
{"HTMLPart", "<h3>Dear passenger 1, welcome to Mailjet!</h3><br />May the delivery force be with you!"},
{"Attachments", new JArray {
new JObject {
{"ContentType", "text/plain"},
{"Filename", "test.txt"},
{"Base64Content", "VGhpcyBpcyB5b3VyIGF0dGFjaGVkIGZpbGUhISEK"}
}
}}
}
});
MailjetResponse response = await client.PostAsync(request);
if (response.IsSuccessStatusCode)
{
Console.WriteLine(string.Format("Total: {0}, Count: {1}\n", response.GetTotal(), response.GetCount()));
Console.WriteLine(response.GetData());
}
else
{
Console.WriteLine(string.Format("StatusCode: {0}\n", response.StatusCode));
Console.WriteLine(string.Format("ErrorInfo: {0}\n", response.GetErrorInfo()));
Console.WriteLine(response.GetData());
Console.WriteLine(string.Format("ErrorMessage: {0}\n", response.GetErrorMessage()));
}
When I get http response it looks like this:
{
"course_editions": {
"2014/SL": [
{
"course_id": "06-DEGZLI0",
"term_id": "2014/SL",
"course_name": {
"en": "Preparation for bachelor exam",
}
},
{
"course_id": "06-DPRALW0",
"term_id": "2014/SL",
"course_name": {
"en": "Work experience",
}
},
{
I would like to be able to extract course title only, f.e.:
Work experience
Preparation for bachelor exam
I've tried this:
string probably_json = GetResponse(url_courses);
object obj = JsonConvert.DeserializeObject(probably_json);
using (StringReader reader = new StringReader(obj.ToString().Replace("\\t", " ").Replace("\\n", "\n")))
{
string line;
int lineNo = 0;
while ((line = reader.ReadLine()) != null)
{
if (line.Contains("en"))
{
string output = line.Substring(0, line.Length-1);
Console.WriteLine(output);
}
++lineNo;
}
} // End Using StreamReader
But that's all I've got:
"en": "Preparation for bachelor exam" "en": "Work experience"
what am I supposed to do, to get course title only ?
If you are using json.net anyways, make it do some work, don't parse yourself:
var result = JObject
.Parse(probably_json)
.SelectTokens("['course_editions'].['2014/SL'].[*].['course_name'].['en']");