Please I need your help here, I could not write the logic to display the deserialized JSON result on tabPage in Winforms C#
public Form1()
{
var path = #"C:\Users\elitebook\source\repos\ExamCBT\question.json";
string jsonFile = File.ReadAllText(path);
Question q = JsonConvert.DeserializeObject<Question>(jsonFile);
InitializeComponent();
}
jsonFile = tabPage2.ToString();
You can use these methods for serializing & deserializing JSON. Just download the Newtonsoft.Json NuGet package.
static class FileHelper
{
public static void JsonSerialize(object obj, string fileName)
{
using (var sw = new System.IO.StreamWriter($"{fileName}.json"))
using (var jw = new Newtonsoft.Json.JsonTextWriter(sw))
{
var serializer = new Newtonsoft.Json.JsonSerializer();
jw.Formatting = Newtonsoft.Json.Formatting.Indented;
serializer.Serialize(jw, obj);
}
}
public static void JsonDeserialize(out string/*object, List<>, or something else*/ obj, string fileName)
{
using (var sr = new System.IO.StreamReader($"{fileName}.json"))
{
using (var jr = new Newtonsoft.Json.JsonTextReader(sr))
{
var serializer = new Newtonsoft.Json.JsonSerializer();
try
{
obj = serializer.Deserialize<string /*object, List<>, or something else...*/>(jr);
}
catch
{
obj = null;
}
}
}
}
}
And you can add JSON data to TabPage like this.
Label label = new Label(); // label can be textbox, button or something else...
FileHelper.JsonDeserialize(out string /*object, List<>, or something else...*/ data, "test");
label.Text = data //data type is string
tabPage1.Controls.Add(label);
Related
I have this code which reads from my json file an array of words
public static string[] GetProfanity()
{
var json = string.Empty;
using (var fs = File.OpenRead("profanity.json"))
using (var sr = new StreamReader(fs, new UTF8Encoding(false)))
json = sr.ReadToEnd();
var profanityJson = JsonConvert.DeserializeObject<ProfanityJson>(json);
return profanityJson.badwords;
}
This is the json
{
"badwords" : ["bad", "stupid"]
}
And i try to access this here
public static bool ProfanityCheck(string inputString)
{
string[] badWords = GetProfanity();
string checkString = inputString.ToLower();
if (badWords.Any(checkString.Contains))
return true;
return false;
}
As requested I access the ProfanityCheck method here
[Command("echo")]
[Description("says whatever the user gives")]
public async Task Echo(CommandContext ctx, [RemainingText] string echoText)
{
bool hasProfanity = ProfanityFilter.ProfanityCheck(echoText);
if(hasProfanity)
{
var errMsg = ProfanityFilter.ErrorMessage();
var errSent = await ctx.Channel.SendMessageAsync(embed: errMsg).ConfigureAwait(false);
Thread.Sleep(3000);
await ctx.Channel.DeleteMessageAsync(errSent).ConfigureAwait(false);
await ctx.Channel.DeleteMessageAsync(ctx.Message).ConfigureAwait(false);
return;
}
await ctx.Channel.SendMessageAsync(echoText).ConfigureAwait(false);
}
and the struct I Deserialize it as
public struct ProfanityJson
{
[JsonProperty("badwords")]
public string[] badwords { get; private set; }
}
but when i attempt to search for this any bad words in a string I pass, nothing happens, no errors in the console, no output otherwise. I have it set up so that it sends me an error message when profanity is found, but in its current state it does nothing when profanity is passed
Your code seems to be correct... I would write the GetProfanity() in another way (and I wouldn't surely reread it every time a word is passed to to ProfanityCheck) but this is tangential to your problem. I've written a minimum testable example:
public class ProfanityJson
{
public string[] badwords { get; set; }
}
public static class ProfanityChecker
{
public static string[] GetProfanity()
{
var json = string.Empty;
using (var fs = File.OpenRead("profanity.json"))
using (var sr = new StreamReader(fs, new UTF8Encoding(false)))
json = sr.ReadToEnd();
var profanityJson = JsonConvert.DeserializeObject<ProfanityJson>(json);
return profanityJson.badwords;
}
public static string[] GetProfanity2()
{
using (var sr = new StreamReader("profanity.json"))
using (var jtr = new JsonTextReader(sr))
{
var ser = new JsonSerializer();
var profanityJson = ser.Deserialize<ProfanityJson>(jtr);
return profanityJson.badwords;
}
}
public static bool ProfanityCheck(string inputString)
{
string[] badWords = GetProfanity2();
Trace.WriteLine($"Loaded {badWords.Length} bad words");
string checkString = inputString.ToLower();
if (badWords.Any(checkString.Contains))
return true;
return false;
}
}
static void Main(string[] args)
{
Console.WriteLine(ProfanityChecker.ProfanityCheck("badder"));
}
So the only idea I have is that you are using a "stale" version of profanity.json. I've added a little loggin in the ProfanityCheck() method. It will go to the Output pane in Visual Studio.
(Would be a mess as a comment)
You could have your class like this:
public class ProfanityJson
{
[JsonProperty("badwords")]
public string[] Badwords { get; set; }
}
Is it like so? Json is case sensitive.
I would like to deserialize part of xml, I tried this, but it does not work.
class Program
{
static void Main(string[] args)
{
var serializer = new XmlSerializer(typeof(Test), new XmlRootAttribute("Test"));
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes("<Root1><Root2><Test><Id>5</Id></Test></Root2></Root1>")))
{
var test = serializer.Deserialize(stream);
}
}
}
public class Test
{
public int Id;
}
How can I say to XmlSerializer to start serialization from <Test>?
Move to desired node with XmlReader.
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes("<Root1><Root2><Test><Id>5</Id></Test></Root2></Root1>")))
using (var reader = XmlReader.Create(stream))
{
reader.ReadToFollowing("Test");
var test = (Test)serializer.Deserialize(reader);
}
I've been working at this and have managed to get the json parsed into a C# object. Now the next step was to parse a json array into a List. I have managed to get the job done but I'm pretty sure there is a better way to convert from BsonArray to a List
using (StreamReader file = File.OpenText(filename))
{
try
{
//first up convert to bson
var jsonSampleData = file.ReadToEnd();
//var bsonSampleData = BsonDocument.Parse(jsonSampleData);
//this would be for a single BSOnDocument
var bsonSampleData = BsonSerializer.Deserialize<BsonArray>(jsonSampleData);
var x = bsonSampleData.ToList();
List<ThePlan> lst = new List<ThePlan>();
foreach (var doc in x)
{
var t = BsonSerializer.Deserialize<ThePlan>(doc.AsBsonDocument);
lst.Add(t);
}
}
catch (Exception ex)
{
throw;
}
Edit-Additional Information
To be clear what I am needing to accomplish is taking the given json document and rehydrate it to List. This is further complicated by my being new to mongo and T is a mongo entity representation.
As Andrei pointed out it works fine:
using (StreamReader file = File.OpenText(filename))
{
var jsonSampleData = file.ReadToEnd();
_thePlan = BsonSerializer.Deserialize<List<ThePlan>>(jsonSampleData);
}
Thinking about my struggles yesterday I think it actually had to do with my json where on my early attempts it looked like this:
{
"_id": "57509afbc6b48d3f33b2dfcd",
...
}
In the process of figuring it all out my json matured to:
{
"_id": { "$oid": "57509afbc6b48d3f33b2dfcd" },
.....
}
The troubles I was having with BsonSerializer was likely my bad json and once that was worked out I wasn't astute enough to go back to the BsonSerielizer and try again.
Either go strongly typed all the way or not typed at all.
strongly typed
Assuming these are your types:
public class BaseObject {
[BsonId] public ObjectId id { get; set; }
[BsonElement("plans")] public List<ThePlan> Plans { get; set; }
}
public class ThePlan {
[BsonElement("i")] public int Integer { get; set; }
[BsonElement("s")] public string String { get; set; }
}
and these test utilities:
void ToJsonTyped(BaseObject bo)
{
var sb = new StringBuilder();
using (TextWriter tw = new StringWriter(sb))
using (BsonWriter bw = new JsonWriter(tw))
{
BsonSerializer.Serialize<BaseObject>(bw, bo);
}
string jsonObject = sb.ToString();
BaseObject bo2 = BsonSerializer.Deserialize<BaseObject>(jsonObject);
Assert.AreEqual(bo, bo2);
}
void ToBsonTyped(BaseObject bo)
{
byte[] bsonObject = null;
using (var ms = new MemoryStream())
using (BsonWriter bw = new BsonBinaryWriter(ms))
{
BsonSerializer.Serialize<BaseObject>(bw, bo);
bsonObject = ms.ToArray();
}
BaseObject bo1 = BsonSerializer.Deserialize<BaseObject>(bsonObject);
Assert.AreEqual (bo, bo1);
}
you can test:
BaseObject bo = new BaseObject() {
Plans = new List<ThePlan>() {
new ThePlan() {Integer=1, String="one" },
new ThePlan() {Integer=2, String="two" },
new ThePlan() {Integer=3, String="three" } } };
ToBsonTyped(bo);
ToJsonTyped(bo);
not typed at all, combo of BsonDocument and BsonArray
test:
BsonDocument doc = new BsonDocument();
var bsonArray = new BsonArray();
bsonArray.Add(new BsonDocument("one", 1));
bsonArray.Add(new BsonDocument("two", 2));
bsonArray.Add(new BsonDocument("three", 3));
doc.Add( new BsonElement("plans", bsonArray));
ToBsonUnTyped(doc);
ToJsonUnTyped(doc);
test utils:
void ToBsonUnTyped(BsonDocument doc) {
byte[] bsonObject = null;
using (var ms = new MemoryStream())
using (BsonWriter bw = new BsonBinaryWriter(ms))
{
BsonSerializer.Serialize<BsonDocument>(bw, doc);
bsonObject = ms.ToArray();
}
BsonDocument docActual = BsonSerializer.Deserialize<BsonDocument>(bsonObject);
Assert.AreEqual (doc, docActual);
}
void ToJsonUnTyped(BsonDocument doc)
{
var sb = new StringBuilder();
using (TextWriter tw = new StringWriter(sb))
using (BsonWriter bw = new JsonWriter(tw))
{
BsonSerializer.Serialize<BsonDocument>(bw, doc);
}
string jsonObject = sb.ToString();
BsonDocument doc2 = BsonSerializer.Deserialize<BsonDocument>(jsonObject);
Assert.AreEqual(doc, doc2);
}
i want to deserialize an xml file and copy those values into csv file.i tried like this.
[Serializable, XmlRoot("Configuration"), XmlType("Configuration")]
public class LabelRequest
{
public string weightoz { get; set; }
public string MailClass { get; set; }
public static void DeSerialization()
{
LabelRequest label = new LabelRequest();
TextReader txtReader = new StreamReader(#"C:\xmlfile.xml");
XmlSerializer xmlSerializer = new XmlSerializer(typeof(LabelRequest));
label = (LabelRequest) xmlSerializer.Deserialize(txtReader);
txtReader.Close();
}
}
and the xml file is as follows
<Labelrequest>
<weightoz>2</weightoz>
<mailclass>abc</mailclass>
</labelrequest>
To write the values to a CSV file shouldn't be too difficult. Your example does not contain any code which writes to a file though. It only deserialises an XML file. Might I suggest something like this.
public static class LabelRequestSerializer
{
public static Label DeserializeXmlFile(string fileName)
{
using (TextReader txtReader = new StreamReader(fileName))
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(LabelRequest));
LabelRequest label = (LabelRequest) xmlSerializer.Deserialize(txtReader);
}
}
public static void SerializeToCsv(LabelRequest labelRequest, string fileName)
{
if (labelRequest == null)
throw new ArgumentNullException("labelRequest");
StringBuilder sb = new StringBuilder();
sb.Append(labelRequest.weightoz);
sb.Append(",");
sb.Append(labelRequest.mailclass);
sb.AppendLine();
using (StreamWriter stream = new StreamWriter(fileName))
{
stream.Write(sb.ToString());
}
}
}
Then you can pass the instance of LabelRequest you want to serialize to these static methods. That way LabelRequest does not know about how to serialize itself from files, which is a nice seperation of concerns. Like this
void SomeMethod()
{
LabelRequest labelRequest = new LabelRequest();
LabelRequestSerializer.SerializeToCsv(labelRequest, #"C:\Path\Goes\Here\label.csv");
}
Edit...
If you really don't want to write out every property manually you can use reflection. However there will be a performance hit by using this. Shouldn't be a problem compared to the file IO though.
public static void SerializeToCsv(LabelRequest labelRequest, string fileName)
{
if (labelRequest == null)
throw new ArgumentNullException("labelRequest");
StringBuilder sb = new StringBuilder();
foreach (PropertyInfo info in labelRequest.GetType() .GetProperties())
{
object value = info.GetValue(labelRequest, null);
sb.Append(value);
sb.Append(", ");
}
sb.AppendLine();
using (StreamWriter stream = new StreamWriter(fileName))
{
stream.Write(sb.ToString());
}
}
I can serialize a list really easy:
List<String> fieldsToNotCopy =new List<String> {"Iteration Path","Iteration ID"};
fieldsToNotCopy.SerializeObject("FieldsToNotMove.xml");
Now I need a method like this:
List<String> loadedList = new List<String();
loadedList.DeserializeObject("FieldsToNotMove.xml");
Is there such a method? Or am I going to need to create an XML reader and load it in that way?
EDIT: Turns out there is no built in SerialzeObject. I had made one earlier in my project and forgot about it. When I found it I thought it was built in. In case you are curious this is the SerializeObject that I made:
// Save an object out to the disk
public static void SerializeObject<T>(this T toSerialize, String filename)
{
XmlSerializer xmlSerializer = new XmlSerializer(toSerialize.GetType());
TextWriter textWriter = new StreamWriter(filename);
xmlSerializer.Serialize(textWriter, toSerialize);
textWriter.Close();
}
There is no such builtin method as SerializeObject but it's not terribly difficult to code one up.
public void SerializeObject(this List<string> list, string fileName) {
var serializer = new XmlSerializer(typeof(List<string>));
using ( var stream = File.OpenWrite(fileName)) {
serializer.Serialize(stream, list);
}
}
And Deserialize
public void Deserialize(this List<string> list, string fileName) {
var serializer = new XmlSerializer(typeof(List<string>));
using ( var stream = File.OpenRead(fileName) ){
var other = (List<string>)(serializer.Deserialize(stream));
list.Clear();
list.AddRange(other);
}
}
These are my serialize/deserialize extension methods that work quite well
public static class SerializationExtensions
{
public static XElement Serialize(this object source)
{
try
{
var serializer = XmlSerializerFactory.GetSerializerFor(source.GetType());
var xdoc = new XDocument();
using (var writer = xdoc.CreateWriter())
{
serializer.Serialize(writer, source, new XmlSerializerNamespaces(new[] { new XmlQualifiedName("", "") }));
}
return (xdoc.Document != null) ? xdoc.Document.Root : new XElement("Error", "Document Missing");
}
catch (Exception x)
{
return new XElement("Error", x.ToString());
}
}
public static T Deserialize<T>(this XElement source) where T : class
{
try
{
var serializer = XmlSerializerFactory.GetSerializerFor(typeof(T));
return (T)serializer.Deserialize(source.CreateReader());
}
catch //(Exception x)
{
return null;
}
}
}
public static class XmlSerializerFactory
{
private static Dictionary<Type, XmlSerializer> serializers = new Dictionary<Type, XmlSerializer>();
public static XmlSerializer GetSerializerFor(Type typeOfT)
{
if (!serializers.ContainsKey(typeOfT))
{
System.Diagnostics.Debug.WriteLine(string.Format("XmlSerializerFactory.GetSerializerFor(typeof({0}));", typeOfT));
var newSerializer = new XmlSerializer(typeOfT);
serializers.Add(typeOfT, newSerializer);
}
return serializers[typeOfT];
}
}
You just need to define a type for your list and use it instead
public class StringList : List<String> { }
Oh, and you don't NEED the XmlSerializerFactory, it's just there since creating a serializer is slow, and if you use the same one over and over this speeds up your app.
I'm not sure whether this will help you but I have dome something which I believe to be similar to you.
//A list that holds my data
private List<Location> locationCollection = new List<Location>();
public bool Load()
{
//For debug purposes
Console.WriteLine("Loading Data");
XmlSerializer serializer = new XmlSerializer(typeof(List<Location>));
FileStream fs = new FileStream("CurrencyData.xml", FileMode.Open);
locationCollection = (List<Location>)serializer.Deserialize(fs);
fs.Close();
Console.WriteLine("Data Loaded");
return true;
}
This allows me to deserialise all my data back into a List<> but i'd advise putting it in a try - catch block for safety. In fact just looking at this now is going to make me rewrite this in a "using" block too.
I hope this helps.
EDIT:
Apologies, just noticed you're trying to do it a different way but i'll leave my answer there anyway.
I was getting error while deserializing to object. The error was "There is an error in XML document (0, 0)". I have modified the Deserialize function originally written by #JaredPar to resolve this error. It may be useful to someone:
public static void Deserialize(this List<string> list, string fileName)
{
XmlRootAttribute xmlRoot = new XmlRootAttribute();
xmlRoot.ElementName = "YourRootElementName";
xmlRoot.IsNullable = true;
var serializer = new XmlSerializer(typeof(List<string>), xmlRoot);
using (var stream = File.OpenRead(fileName))
{
var other = (List<string>)(serializer.Deserialize(stream));
list.Clear();
list.AddRange(other);
}
}
Create a list of products be serialized
List<string> Products = new List<string>
{
new string("Product 1"),
new string("Product 2"),
new string("Product 3"),
new string("Product 4")
};
Serialization
using (FileStream fs = new FileStream(#"C:\products.txt", FileMode.Create))
{
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(fs, Products);
}
Deserialization
using (FileStream fs = new FileStream(#"C:\products.txt", FileMode.Open))
{
BinaryFormatter bf = new BinaryFormatter();
var productList = (List<string>)bf.Deserialize(fs);
}