Null reference in C# Mono / GTK# - c#

I am trying to create a simple note-taking application for my own use. The idea is to learn C#/Mono XML editing.
I can't find a NullReference that the compiler is complaining about. No idea why. I can't see it. After few days of searching I give up... help. :)
Here is the code that is making a bug. The application runs fine until I press a button to Add new note. It just crashes. The add_activated function runs when a button is pressed and it should use AddNote function.
The code is incomplete and it certainly has some logic bugs. But I can handle those. I'm just wondering why it won't run.
MainActivity.cs:
// (...)
protected void add_activated (object sender, System.EventArgs e)
{
Gtk.TextBuffer buffer;
buffer = textview1.Buffer;
Note note = new Note(entry3.Text, buffer.Text);
AddNote (note);
}
public static void AddNote (Note note)
{
string xmlFile = "/home/tomasz/.keeper/keeper.xml";
XmlDocument xmlDoc = new XmlDocument ();
xmlDoc.Load (xmlFile);
XmlNode xmlRoot = xmlDoc.CreateElement("keeper");
if (!xmlDoc.DocumentElement.Name.Equals("keeper") )
{
xmlDoc.AppendChild (xmlRoot);
}
XmlNode xmlNote = xmlDoc.CreateElement ("note");
XmlNode xmlTitle = xmlDoc.CreateElement ("title");
XmlNode xmlText = xmlDoc.CreateElement ("text");
xmlRoot.InsertAfter (xmlRoot.LastChild, xmlNote);
xmlTitle.InnerText = note.Title;
xmlNote.InsertAfter (xmlNote.LastChild, xmlTitle);
xmlText.InnerText = note.Text;
xmlNote.InsertAfter (xmlNote.LastChild, xmlText);
xmlDoc.Save (xmlFile);
}
protected void remove_activated (object sender, System.EventArgs e)
{
throw new System.NotImplementedException ();
}
}
}
Note.cs:
using System;
namespace Keeper
{
public class Note
{
private string title;
private string text;
public string Title {
get
{
return this.title;
}
set
{
this.title = value;
}
}
public string Text
{
get
{
return this.text;
}
set
{
this.text = value;
}
}
public Note (string title, string text)
{
this.Title = title;
this.Text = text;
}
}
}

The immediate problem is that you got the arguments to InserAfter mixed up. First one should be the node to insert and the second one should be the reference node. The root element has no children yet, so LastChild is going to be null and hence the exeption. Using null as a reference point is valid, but not as a node to add.
There are other issues but you said you are able to fix those, so there you go.

Related

C# Task program unable to add new items in Windows Form App

I'm taking a rubbish C# course online, and it wants me to create a program that is like a chore list that the user can use add, remove, or clear items on the list.
The problem I am having is when I add text to the textbox and then click a button(say Add front) nothing happens.
Here are some code snippet and a pic:
LinkedList<string> todoList = new LinkedList<string>();
public void DisplayList()
{
ItemTextBox.Text = ""; //this is the very top box.
ToDoListBox.Text = "";
foreach(string MyString in todoList)
{
ToDoListBox.Text += MyString;
}
}
private void AddFrontButton_Click(object sender, EventArgs e)
{
System.Collections.IEnumerator iterator = todoList.GetEnumerator();
//If the user desides to add the task to the front of the list.
if(ItemTextBox.Text != "")
{
todoList.AddFirst(ItemTextBox.Text);
DisplayList();
}
}
And here are some Instructions from the course:
Add the following code within your class:
Declare a LinkedList variable containing string data, named todoList.
Create a method called DisplayList(), which does the following:
Clear the contents of the ItemTextBox and the ToDoListBox.
Use a foreach loop to walk each string in the todoList.
Inside the loop, add the current string from todoList to the ToDoListBox
Create event handler function for the AddFrontButton and add the following logic:
If there is any text in the ItemTextBox add the text to the front of the todoList
Call the DisplayList() function to refresh the ToDoListBox on the screen
For sure your code will not do what you intend to do. There are many things wrong with it. I haven't tested it, but here is what the code should roughly look like:
LinkedList<string> todoList = new LinkedList<string>();
public void DisplayList()
{
ItemTextBox.Text = ""; //this is the very top box.
ToDoListBox.Items.Clear();
foreach(string MyString in todoList)
{
ToDoListBox.Items.Add(MyString);
}
}
private void AddFrontButton_Click(object sender, EventArgs e)
{
System.Collections.IEnumerator iterator = todoList.GetEnumerator();
//If the user desides to add the task to the front of the list.
if(!String.IsNullOrWhiteSpace(ItemTextBox.Text))
{
todoList.AddFirst(ItemTextBox.Text);
DisplayList();
}
}

How to figure out when a job number is not used

On our job database we have a http address that ends with "projects/Project/Entry/5893" The 5893 is the job number that will change job to job.
I have a timer set to go through each number till it gets this page End Page. So on the End Page HtmlElement does not exist so it gives me the System.NullReferenceException and there for i know the last used job number. But the Problem is that the Exception does not pop up. Does anyone know an easier way to do this. Sorry for not showing the complete webpage address it has sensitive information.
private int a = -1;
private string NJNumber = File.ReadAllText(#"...\CurrentJobNumber.txt");
//The Last Confirmed Number by me and where to start searching from.
private void NewJob_Click(object sender, EventArgs e)
{
HtmlDocument doc = nwJob.Document;
a = Convert.ToInt32(NJNumber);
JobNumberTimer.Start();
}
private void JobNumberTimer_Tick(object sender, EventArgs e)
{
HtmlDocument doc = nwJob.Document;
string aJN = a.ToString();
try
{
nwJob.Navigate("..../projects/Project/Entry/" + aJN);
HtmlElement njname = doc.GetElementById("Name");
a += 1;
}
catch(System.NullReferenceException)
{ lblJobNumber.Text = a.ToString();
JobNumberTimer.Stop();
}
}
I don't think that HtmlDocument.GetElementById will throw a NullReferenceException.
You could try and check the body of the the html doc for something on the error page.
doc.Body.InnerText.Contains("somthing to search for")

Cannot get rendered html via WebBrowser

I want to get html code from website. In Browser I usually can just click on ‘View Page Source’ in context menu or something similar. But how can I automatized it? I’ve tried it with WebBrowser class but sometimes it doesn’t work. I am not web developer so I don’t really know if my approach at least make sense. I think main problem is that I sometimes get html where not all code was executed. Hence it is uncompleted. I have problem with e.g. this site: http://www.sreality.cz/en/search/for-sale/praha
My code (I’ve tried to make it small but runnable on its own):
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace WebBrowserForm
{
internal static class Program
{
[STAThread]
private static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
for (int i = 0; i < 10; i++)
{
Form1 f = new Form1();
f.ShowDialog();
}
// Now I can check Form1.List and see that some html is final and some is not
}
}
public class Form1 : Form
{
public static List<string> List = new List<string>();
private const string Url = "http://www.sreality.cz/en/search/for-sale/praha";
private System.Windows.Forms.WebBrowser webBrowser1;
public Form1()
{
this.webBrowser1 = new System.Windows.Forms.WebBrowser();
this.SuspendLayout();
this.webBrowser1.Dock = System.Windows.Forms.DockStyle.Fill;
this.webBrowser1.Name = "webBrowser1";
this.webBrowser1.TabIndex = 0;
this.ResumeLayout(false);
Load += new EventHandler(Form1_Load);
this.webBrowser1.ObjectForScripting = new MyScript();
}
private void Form1_Load(object sender, EventArgs e)
{
webBrowser1.Navigate(Url);
webBrowser1.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted);
}
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
if (webBrowser1.ReadyState == WebBrowserReadyState.Complete)
{
// Final html for 99% of web pages, but unfortunately not for all
string tst = webBrowser1.Document.GetElementsByTagName("HTML")[0].OuterHtml;
webBrowser1.DocumentCompleted -= new WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted);
Application.DoEvents();
webBrowser1.Navigate("javascript: window.external.CallServerSideCode();");
Application.DoEvents();
}
}
[ComVisible(true)]
public class MyScript
{
public void CallServerSideCode()
{
HtmlDocument doc = ((Form1)Application.OpenForms[0]).webBrowser1.Document;
string renderedHtml = doc.GetElementsByTagName("HTML")[0].OuterHtml;
// here I sometimes get full html but sometimes the same as in webBrowser1_DocumentCompleted method
List.Add(renderedHtml);
((Form1)Application.OpenForms[0]).Close();
}
}
}
}
I would expect that in ‘webBrowser1_DocumentCompleted’ method I could get final html. It usually works, but with this site it doesn’t. So I’ve tried get html in my own code which should be executed in web site -> method ‘CallServerSideCode’. What is strange that sometimes I get final html (basically the same as if I do it manually via Browser) but sometimes not. I think the problem is caused because my script start before whole web site is rendered instead after. But I am not really sure since this kind of things are far from my comfort zone and I don’t really understand what I am doing. I’m just trying to apply something what I found on the internet.
So, does anyone knows what is wrong with the code? Or even more importantly how to easily get final html from the site?
Any help appreciated.
You should use WebClient class to download HTML page. No display control necessary.
You want method DownloadString
May be it will be helpful if you add calling of your external function to the end of the body and wrap it by Jquery "ondomready" function. I mean something like this:
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
if (webBrowser1.ReadyState == WebBrowserReadyState.Complete)
{
// Final html for 99% of web pages, but unfortunately not for all
string tst = webBrowser1.Document.GetElementsByTagName("HTML")[0].OuterHtml;
webBrowser1.DocumentCompleted -= new WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted);
HtmlElement body = webBrowser1.Document.GetElementsByTagName("body")[0];
HtmlElement scriptEl = webBrowser1.Document.CreateElement("script");
IHTMLScriptElement element = (IHTMLScriptElement)scriptEl.DomElement;
element.text = "$(function() { window.external.CallServerSideCode(); });";
body.AppendChild(scriptEl);
}
}
[ComVisible(true)]
public class MyScript
{
public void CallServerSideCode()
{
HtmlDocument doc = ((Form1)Application.OpenForms[0]).webBrowser1.Document;
string renderedHtml = doc.GetElementsByTagName("HTML")[0].OuterHtml;
// here I sometimes get full html but sometimes the same as in webBrowser1_DocumentCompleted method
List.Add(renderedHtml);
((Form1)Application.OpenForms[0]).Close();
}
}

Creating a Search button with regex

So I'm basically trying to create a search button.
This search is using REGEX.
I think I have it correct but it's not working, Can someone tell me how / where i've gone wrong, Not coded in AGES...
public void SearchFunction(string searchtext)
{
SupporterId();
ReferenceNumber();
ConsignmentNumber();
}
private static void SupporterId()
{
const string sId= "";
var supporterId = Regex.IsMatch(sId, #"^[A-F,S,R][0-9]{3,6}$", RegexOptions.IgnoreCase);
}
private static void ReferenceNumber()
{
const string refNumber = "";
var referenceNumber = Regex.IsMatch(refNumber, #"^[ABN158][0-9]{6,17}$", RegexOptions.IgnoreCase);
}
private static void ConsignmentNumber()
{
const string conNumber = "";
var consignmentNumber = Regex.IsMatch(conNumber, #"&[0-9]{14}$", RegexOptions.IgnoreCase);
}
}
}
Those are my Regex, And this is my code behind..
protected void CheckStateClick(object sender, EventArgs e)
{
ConsignmentSearch();
}
private void ConsignmentSearch()
{
var searchclass = new RegexMethods();
searchclass.SearchFunction(txtReferenceNumber.Text);
}
Can anyone tell me where I have gone wrong and HOW I can fix it, Please don't tell me oh your missing this an then don't tell me how to fix it.
IF you can tell me how / what needs adding to be fixed example: add this line of code here .... < >
Please and thank you.
__
THIS IS THE ERROR
Test 'M:DeliveryInputSystem.Default.AddBox_Click(System.Object,System.EventArgs)' failed: Object reference not set to an instance of an object.
System.NullReferenceException: Object reference not set to an instance of an object.
Default.aspx.cs(113,0): at DeliveryInputSystem.Default.AddBox_Click(Object sender, EventArgs e)
I may be wrong, but it looks like you are only checking empty strings...
How about checking your searchtext like this:
public void SearchFunction(string searchtext)
{
SupporterId(searchtext);
ReferenceNumber(searchtext);
ConsignmentNumber(searchtext);
}
private static void SupporterId(string sId)
{
var supporterId = Regex.IsMatch(sId, #"^[A-F,S,R][0-9]{3,6}$", RegexOptions.IgnoreCase);
}
private static void ReferenceNumber(string refNumber)
{
var referenceNumber = Regex.IsMatch(refNumber, #"^[ABN158][0-9]{6,17}$", RegexOptions.IgnoreCase);
}
private static void ConsignmentNumber(string conNumber)
{
var consignmentNumber = Regex.IsMatch(conNumber, #"&[0-9]{14}$", RegexOptions.IgnoreCase);
}
However, if I understand your code correctly, your searchtext variable only contains the txtReferenceNumber.Text text, so you should only run the ReferenceNumber(string searchtext) method on it.
You provided error text:
__ THIS IS THE ERROR Test'
M:DeliveryInputSystem.Default.AddBox_Click(System.Object,System.EventArgs)' failed:
Object reference not set to an instance of an object.
System.NullReferenceException:
Object reference not set to an instance of an object.
Default.aspx.cs(113,0): at DeliveryInputSystem.Default.AddBox_Click(Object sender, EventArgs e)
There is written cause of error: NullReferenceException and where does it occur Default.aspx.cs(113,0). You need to analyze what is there, in line 113 in Default.aspx.cs and why may it cause NullReferenceException.
If you don't know where to start, start with documentation. According to MSDN documentation for NullReferenceException class:
A NullReferenceException exception is thrown when you try to access a member on a type whose value is null.
You have often also an example there:
1: List<String> names;
2: if (sth) names = new List<String>();
3: names.Add("Major Major Major")
If sth is false then no instance is assigned to names and exception will be thrown.

Read xml from URL

This is what I have so far. I am trying to just read the XML from the URL and just get for example temperature, humidity....etc.... But every time I try something else it gives me an error. I want to retrieve the information and put it in a label.
namespace WindowsFormsApplication1 {
public partial class Form1: Form {
public Form1() {
InitializeComponent();
}
private void btnSubmit_Click(object sender, EventArgs e) {
String zip = txtZip.Text;
XmlDocument weatherURL = new XmlDocument();
weatherURL.Load("http://api.wunderground.com/api/"
your_key "/conditions/q/" + zip + ".xml");
foreach(XmlNode nodeselect in weatherURL.SelectNodes("response/current_observation"));
}
}
}
It took me a bit of trial and error but I've got it. In C# make sure you are using - using System.Xml;
Here is the code using wunderground API. In order for this to work make sure you sign up for a key other wise it will not work. Where is say this your_key that is where you put in your key. It should look like something like this. I used a button and three labels to display the information.
namespace wfats2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
XmlDocument doc1 = new XmlDocument();
doc1.Load("http://api.wunderground.com/api/your_key/conditions/q/92135.xml");
XmlElement root = doc1.DocumentElement;
XmlNodeList nodes = root.SelectNodes("/response/current_observation");
foreach (XmlNode node in nodes)
{
string tempf = node["temp_f"].InnerText;
string tempc = node["temp_c"].InnerText;
string feels = node["feelslike_f"].InnerText;
label2.Text = tempf;
label4.Text = tempc;
label6.Text = feels;
}
}
}
}
When you press the button you will get the information displayed in the labels assign. I am still experimenting and you are able to have some sort of refresh every so often instead of pressing the button every time to get an update.
First off yeah you need to give more information in your question but off hand I can see that you have "your_key" inside of your URL. You are probably needing to replace that with your API key for this to work.

Categories