C# Read/Write Json Problem with current code - c#

Error: error CS0103: The name 'JsonConvert' does not exist in the current context
I have the latest Newtonsoft download and I cant figure out any way to fix this I've gone over about 50 different links all saying to install it. Which it is.
Am I missing something small? I am just trying to add my json elements to a list so I can use them in a program and then write back to the Json file. If this cant work can someone link or show me another way to do this in c#?
using System.IO;
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;
namespace Newtonsoft.Json {
public class CustomControls : MonoBehaviour
{
private List<string> controls;
//public object JsonConvert { get; private set; }
// Start is called before the first frame update
void Start()
{
LoadJson();
for (int i = 0; i < controls.Count; i++)
{
Debug.Log(controls[i].ToString());
}
}
public void LoadJson()
{
using (StreamReader r = new StreamReader("CustomControls.json"))
{
string json = r.ReadToEnd();
controls = JsonConvert.DeserializeObject<List<string>>(json);
}
}
}
}

Change the name of the namespace in your code
using System.IO;
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;
namespace AnythingOtherThanNewtonsoft.Json {
public class CustomControls : MonoBehaviour
{
private List<string> controls;
//public object JsonConvert { get; private set; }
// Start is called before the first frame update
void Start()
{
LoadJson();
for (int i = 0; i < controls.Count; i++)
{
Debug.Log(controls[i].ToString());
}
}
public void LoadJson()
{
using (StreamReader r = new StreamReader("CustomControls.json"))
{
string json = r.ReadToEnd();
controls = JsonConvert.DeserializeObject<List<string>>(json);
}
}
}
}

If you want or need to use Newtonsoft.Json for some reason, I highly recommend you this guide.
Else, here is an alternative for your case, in which you can use unity`s JsonUtility.
You only need to wrap it in a class
using System.IO;
using UnityEngine;
using System.Collections.Generic;
public class MyControls{
public List<string> controls;
}
public class CustomControls : MonoBehaviour
{
private MyControls myControls;
void Start()
{
SaveJson();
LoadJson();
for (int i = 0; i < myControls.controls.Count; i++)
{
Debug.Log(myControls.controls[i]);//No need to use ToString() here, it`s already a string
}
}
public void SaveJson()
{
MyControls testControls = new MyControls() //Creates a new instance of MyControls
{
controls = new List<string>(2) {"a", "b"} //Your list of strings should go here.
};
File.WriteAllText("CustomControls.json", JsonUtility.ToJson(testControls));
}
public void LoadJson()
{
using (StreamReader r = new StreamReader("CustomControls.json"))
{
string json = r.ReadToEnd();
myControls = JsonUtility.FromJson<MyControls>(json);
}
}
}
Edit: Added an example on how to save a json file using JsonUtility
The file created have this on it {"controls":["a","b"]}

Related

Generating partial classes using source generator removes original class

So I'm experimenting with the new ISourceGenerator system to generate a few I18n strings & classes from XML files. This works but now I want to extend an existing partial class using a source generator, but whenever I do the original class contents become inaccessible! This is the class I have:
// File: Strings.cs
namespace MyProject.I18n
{
public static partial class Strings
{
public const string Options = "Options";
}
}
This is what I'm generating:
// Generated file: GeneratedStrings.cs
namespace MyProject.I18n
{
public static partial class Strings
{
public const string MainMenu = "Main menu";
}
}
This is how I'm generating it (MVCE):
using System.Linq;
using System.Text;
using System.Xml.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Text;
[Generator]
public class I18NGenerator : ISourceGenerator
{
private const string XML_EXAMPLE = #"
<Strings>
<MainMenu>Main menu</MainMenu>
</Strings>
";
private StringBuilder sb = null!;
private int indentation;
public void Initialize(GeneratorInitializationContext context)
{
sb = new StringBuilder();
indentation = 0;
}
public void Execute(GeneratorExecutionContext context)
{
var root = XDocument.Parse(XML_EXAMPLE).Root!;
void Process(XElement element)
{
var text = element.Nodes().FirstOrDefault(node => node is XText);
if (text is XText xText)
{
IndentedLn($#"public static string {element.Name.LocalName} = ""{xText.Value}"";");
}
else
{
BeginBlock($"public static partial class {element.Name.LocalName}");
foreach (var xElement in element.Elements())
Process(xElement);
EndBlock();
}
}
BeginBlock("namespace MyProject.I18n");
Process(root);
EndBlock();
context.AddSource("GeneratedStrings.cs", SourceText.From(sb.ToString(), Encoding.UTF8));
}
private void Indent()
{
indentation++;
}
private void Dedent()
{
indentation--;
}
private void BeginBlock(string statement = "")
{
if (statement.Length != 0)
IndentedLn(statement);
IndentedLn("{");
Indent();
}
private void EndBlock()
{
Dedent();
IndentedLn("}");
}
private void Raw(string text) => sb.Append(text);
private void Indented(string code)
{
for (var i = 0; i < indentation; i++)
Raw("\t");
Raw(code);
}
private void IndentedLn(string code) => Indented(code + "\n");
}
Trying to access Strings.Options gives the compilation error 'Strings' does not contain a definition for 'Options'.
I can add that if I generate BOTH files they merge just fine.

how to add to the list an object of class property in c sharp

I cannot add class instances correctly to a List. It adds only the last object. And when I debug the List vocabulary shows only adding the last class instance. So by second looping it has two entries of second object, by third looping it has three entries of third object. What I am doing wrong. Here is my code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace myVocabulary
{
public class Word
{
string _original_word;
string _translated_word;
public string Original_Word
{
get
{
return this._original_word;
}
set
{
this._original_word = value;
}
}
public string Translated_Word
{
get
{
return this._translated_word;
}
set
{
this._translated_word = value;
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace myVocabulary
{
class Program
{
static List<Word> vocabulary = new List<Word>();
static void Main(string[] args)
{
Word entry = new Word();
for (int i = 0; i < 5; i++)
{
Console.WriteLine("Enter word");
entry.Original_Word = Console.ReadLine();
Console.WriteLine("Enter Translation");
entry.Translated_Word = Console.ReadLine();
vocabulary.Add(entry);
}
}
}
}
Try this - You need to create a new Word object with each iteration of your loop, otherwise you're just overwriting the same instance repeatedly.
namespace myVocabulary
{
class Program
{
static List<Word> vocabulary = new List<Word>();
static void Main(string[] args)
{
for (int i = 0; i < 5; i++)
{
Word entry = new Word();
Console.WriteLine("Enter word");
entry.Original_Word = Console.ReadLine();
Console.WriteLine("Enter Translation");
entry.Translated_Word = Console.ReadLine();
vocabulary.Add(entry);
}
}
}
}

Bankteller console application

I'm making a simple application to simulate the bankteller problem.
What I'm trying to simulate is:
You have 4 counters in a store. 1 counter is open. Customers start coming in and enter the line for the first counter.
When the fourth customer enters the line for the first counter, another counter should open. The line should be equally divided between the 2 counters.When the customer at the second counter is helped and no new customers enter the line, the counter should close. Basically 4 is too many.
I can't seem to figure it out. I know I need to use a queue. But how? Could someone give me an example in console application? Preferable C#.
Thanks in advance.
Here is what I tried so far,
register class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RegisterCounter
{
class Register
{
private int customerCount;
public Queue<Customer> Line = new Queue<Customer>();
public Register()
{
customerCount = 2;
}
public Register(int customerCount)
{
this.customerCount = customerCount;
}
public int getCustomers()
{
return customerCount;
}
}
}
Customer class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RegisterCounter
{
class Customer
{
private int checkoutTime;
public Customer()
{
checkoutTime = 3;
}
public Customer(int checkoutTime)
{
this.checkoutTime = checkoutTime;
}
public int GetCheckoutTime()
{
return checkoutTime;
}
}
}
Register manager:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace RegisterCounter
{
class RegisterManager
{
public List<Register> registers = new List<Register>();
Register r1 = new Register();
Customer c1 = new Customer();
public RegisterManager()
{
registers.Add(r1);
}
public void ManageCustomers()
{
for (int i = 0; i < registers.Count; i++)
{
registers.Insert(i, new Register());
if (i / 4 <= registers..Line.Count)
{
}
}
}
}
}

I can't assign values to the "List Collection" in my class

This is my class That contains two List collections that will store input that is sent over from my main form. As of right now it have no compiling errors in my class, however I am not sure if it is correct. What it is suppose to do is receive input and display it when called.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace EmployeeRoster
{
public class Employee
{
List<string> name = new List<string>();
List<int> iDnumber = new List<int>();
public void setEmployeeName( List < string> employeenames, string names)
{
employeenames.Add(names);
employeenames = name;
}
public List <string> getEmployeeName()
{
return name;
}
public void setEmployeeNumber( List < int > employeeId, int numbers)
{
employeeId.Add(numbers);
employeeId = iDnumber;
}
public List<int> getEmployeeName()
{
return iDnumber;
}
}
}
I am Trying To assign names to my list that I have created in my class above, However I am trying this code below and I am receiving 2 errors
// Error Cannot implicitly convert type 'System.Collections.Generic.List' to 'string'
// Error No overload for method 'setEmployeeName' takes 1 arguments
What Is the correct way to send arguments into Class in order to fill my list?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace EmployeeRoster
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Employee chart = new Employee();
List < Employee > names = new List < Employee > ();
text1.Text = names; // Error Cannot implicitly convert type 'System.Collections.Generic.List<EmployeeRoster.Employee>' to 'string'
chart.setEmployeeName(names); // Error No overload for method 'setEmployeeName' takes 1 arguments
}
}
}
text1.text = Convert.ToString(names);
You can convert it on the fly like that.
I don't believe you need to pass the collection over to the class. The class can instantiate and add the strings to the collection for you.

Visual Studio gives a NullReferenceException when trying to add my control!

Here's the error:
It says the source of the exception is on Line20 of my class. Here is my class:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections.ObjectModel;
namespace WebServiceScanner
{
public partial class imageList : UserControl
{
private int XPosition = 0;
public imageList()
{
InitializeComponent();
Images.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(Images_CollectionChanged);
}
public ObservableCollection<selectablePicture> Images { get; set; }
public void AddImage(selectablePicture image)
{
Images.Add(image);
}
public void RemoveImage(selectablePicture image)
{
Images.Remove(image);
}
public void MoveImageLeft(int index)
{
selectablePicture tmpImage = Images[index];
Images[index] = Images[index - 1];
Images[index - 1] = tmpImage;
}
public void MoveImageRight(int index)
{
selectablePicture tmpImage = Images[index];
Images[index] = Images[index + 1];
Images[index + 1] = tmpImage;
}
void Images_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
RedrawImages();
}
private void RedrawImages()
{
foreach (var picture in Images)
{
picture.Location = new Point(XPosition + panel1.AutoScrollPosition.X, 0);
XPosition += 130;
panel1.Controls.Add(picture);
}
}
}
}
Maybe I'm doing something dumb like setting an event handler at the constructor. Any ideas? This user control isn't really that complex, so there are few places where something could be wrong.
If you guys need more information please let me know.
Add a statement to instantiate Images.
public imageList()
{
InitializeComponent();
Images = new ObservableCollection<selectablePicture>();
Images.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(Images_CollectionChanged);
}
I'm guessing it is something to do with the fact that Images isn't set to any value so the control is trying to render it for DesignView but Images is null hence the NullReferenceException. It's probably the code in the Constructor when it tries to register against the Images which will probably run before any injection code setting images.
Does < selectablePicture > have a parameterless public constructor? And are you instancing Images?

Categories