I want to be able to display balance to label and my code is not working. This is code I got so far:
SqlDataReader readdata;
{
sqlCommandbalance.Connection.Open();
sqlCommandbalance.Parameters["#accountID"].Value = show.accoundID;
readdata = sqlCommandbalance.ExecuteReader();
string balanceDB = null;
while (readdata.Read())
{
balanceDB = readdata["balance"].ToString();
}
sqlCommandbalance.Connection.Close();
balanceShow.Text += " " + balanceDB.ToString();
}
On this line - balanceShow.Text += " " + balanceDB.ToString(); got a error saying Object reference not set to an instance of an object.
You're calling balanceDB.ToString(), when balanceDB will be null if the data reader contains no rows.
Note that balanceDB.ToString() is redundant, since balanceDB is already a string. Just take out the ToString call.
You could also initialize balanceDB as
string balanceDB = "";
Originally you set balanceDB = null;.
If no data was found, then no assignment will be made to balanceDB in the while loop, so it stays undefined.
It's because of string balanceDB = null;
Set that to string balanceDB = string.Empty; and you should be OK
Readdata.read probably returned false, making the while to never run. Thus balanceDB is still null.
Looks like your query is returning an empty set. You should check for that before you set the balanceShow.Text:
if (balanceDB != null) {
balanceShow.Text += " " + balanceDB.ToString();
} else {
// tell the user that id: show.accoundID has no balance
}
Probably your code is returing null in dataRader and consequentily you're tanking an null value on balanceDB. I recomend you do something like this:
public static string GetBalance() {
string result = string.Emtpy;
using (var connection = /* Build your SqlConnection */) {
using (var cmd = new SqlCommand("your select command here", connection) {
try
{
connection.Open();
// you don't need a reader to take just a single value
object value = cmd.ExecuteScalar();
if (value != null)
result = value.ToString();
}
catch(Exception ex)
{
/* you've got an error */
}
finally
{
connection.Close();
}
}
}
return result;
}
and in your page:
string balance = GetBalance();
if (!string.IsNullOrEmpty(balance))
balanceShow.Text += string.Contat(" ", balance);
if you wish to concat the balanceShow label, use '+=' operator, instead of this you just '='.
PS: Sorry for my english!
Related
This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 3 years ago.
Why do I get a NullReferenceException in the following code?
private string FileR ( string name )
{
string[] content = ReadSite(name, Protocol.read, url);
Request_Template newCon;
string[] final = new string[content.Length];
for (int i = 0; i < content.Length; i++)
{
if (content[i].Equals(null))
{
return "content [" + i + "] returns null";
}
newCon = JsonSerializer.Deserialize<Request_Template>(content[i]);
if (newCon.Sender.Contains(myAccount.Username))
{
newCon.Sender = "Me";
}
string sender = newCon.Sender;
string message = newCon.Message;
final[i] = sender + ":\t" + message;
}
string nFinal = string.Concat(final);
Thread.Sleep(10);
return nFinal;
}
string[] ReadSite(string filename, Protocol p, string uri)
{
Read_Template temp = new Read_Template
{
Chat = filename,
Code = key1
};
string myUrl = JsonSerializer.Serialize(temp);
WebClient web = new WebClient();
Stream stream = web.OpenRead(uri + "/" + myUrl);
int length = 0;
while (new StreamReader(stream).ReadLine() != null)
{
length++;
}
string[] content = new string[length];
using (StreamReader reader = new StreamReader(stream))
{
for (int i = 0; i < length; i++)
{
content[i] = reader.ReadLine();
}
}
return content;
}
I've tried using the debugging tools with no avail. When I ran the code, it said that the error came from string [] final = new string [content.Length];
and for (int i = 0; i < content.Length; i++).That lead me to assume that content was null. But when I used the watch window and it said that the variable content cannot be determined. How do I fix this?
I strongly suspect that the problem is actually here:
if (content[i].Equals(null))
If content[i] is genuinely null, then calling content[i].Equals will throw a NullReferenceException. That test should be written as:
if (content[i] is null)`
Or (for C# 6 or older):
if (content[i] == null)`
Now if ReadSite didn't have a bug in, you shouldn't need that check at all - because ReadSite should return an array of non-null string references. However, the way that you're populating the array is broken. You're currently:
Creating a StreamReader around the stream
Reading from the reader until you run out of data
Creating a new array of the "right" length
Creating another StreamReader around the same stream - which is by now at the end
Reading from the reader however many times you read a line originally
Because the stream is already at the end, ReadLine() is going to return null on every iteration.
Instead, you should just read once, populating a list as you go, like this:
List<string> content = new List<string>();
using (var stream = web.OpenRead(uri + "/" + myUrl))
{
using (var reader = new StreamReader(stream))
{
string line;
while ((line = reader.ReadLine()) is object)
{
content.Add(line);
}
}
}
return content;
That's returning a List<string>, so you'd want to change your ReadSite return type to List<string> or perhaps IReadOnlyList<string>. If you really need it to return an array, you could return content.ToArray() instead.
(Ideally, move to using HttpClient as well, but that's a different story.)
private string FileR ( string name )
{
// ReadSite always returns a content that has length 0 or more. string[] content will never equals null.
// TEST: string[] test = new string[0]; test == null -> False
string[] content = ReadSite(name, Protocol.read, url);
Request_Template newCon;
string[] final = new string[content.Length];
// if content.Length == 0, this loop will never occur and you wont get any NREs.
for (int i = 0; i < content.Length; i++)
{
// It is highly unlikely that a reader.ReadLine() would generate a null but
// just in case it does, use == null instead of .Equals() method. When content[i] == null, you cannot use .Equals() method since nulls dont have Equals method.
if (content[i].Equals(null))
{
return "content [" + i + "] returns null";
}
// If you have checked that content[i] is Not empty space or null, you might
//end up with newCon == null if Deserialization fails. Cover this around try / catch.
newCon = JsonSerializer.Deserialize<Request_Template>(content[i]);
// If deserialization fails, this will throw NRE because nulls wont have
// Sender as a property or array. Check if newCon == null or not. Also,
// check if Sender was correctly initialized as an array/list.. as it could
// be null. nulls wont have Contains as a method.
if (newCon.Sender.Contains(myAccount.Username))
{
newCon.Sender = "Me";
}
string sender = newCon.Sender;
string message = newCon.Message;
// This should work correctly as its dependent on content.length. If the
// loop is happening, then there is at least one final element that can be updated.
final[i] = sender + ":\t" + message;
}
string nFinal = string.Concat(final);
Thread.Sleep(10);
return nFinal;
}
in debugging my wcf call its skipping the while loop and not reading the internal data. I've been bouncing through SO and msdn for help and nothing seems to stand out. Anyone have any clues as to what I'm missing or doing to cause this loop to not iterate through?
Solution: this was a DB problem, once I updated the Oracle DB values the query ran in SQL developer and debugging is working in VS2010.
Thanks
using (connection)
{
try {
connection.ConnectionString = connString;
OracleCommand command = new OracleCommand(sqlString, connection);
connection.Open();
OracleDataReader reader = command.ExecuteReader();
while (reader.Read()) {
td.TNAME = reader.IsDBNull(0) ? " " : reader.GetValue(0).ToString();
td.TASK = reader.IsDBNull(1) ? " " : reader.GetValue(1).ToString();
td.STATUS = reader.IsDBNull(2) ? " " : reader.GetValue(2).ToString();
td.COMPLETE = reader.IsDBNull(3) ? " " : reader.GetValue(3).ToString();
td.PRIORITY = reader.IsDBNull(4) ? 0 : Convert.ToInt32(reader.GetValue(4));
tl.Add(td);
}
//while (reader.NextResult());
reader.Close();
} catch (Exception ex) {
myErr = ex.Message;
}
}
return tl;
If you're actually getting to the while statement without execptions, then the obvious answer is that your datareader has no data. Try examining the value of reader.HasRows before the while loop. I imagine it will be false. Does your sql statement actually return data in SQL Developer?
There are two possible reasons for the loop to not execute:
There is an exception from the code that precedes the loop.
reader.Read() doesn't return any data.
Of course, if your loop never executes then there is no data returned from the query, but I see another problem in your code. The variable td is never re-initialized and in every loop you add to the list the same variable updated with the values extracted from the current loop values.
So you end with the value of the last loop in your tl (whatever is it)
I think you should write
while (reader.Read())
{
td = new YourTDClass(); // Create a new instance of an element of td class
td.TNAME = reader.IsDBNull(0) ? " " : reader.GetValue(0).ToString();
td.TASK = reader.IsDBNull(1) ? " " : reader.GetValue(1).ToString();
td.STATUS = reader.IsDBNull(2) ? " " : reader.GetValue(2).ToString();
td.COMPLETE = reader.IsDBNull(3) ? " " : reader.GetValue(3).ToString();
td.PRIORITY = reader.IsDBNull(4) ? 0 : Convert.ToInt32(reader.GetValue(4));
tl.Add(td);
}
I think you should write more easily:
var list = new List<dynamic>();
while(dr.Read())
{
var value = new YourClass {
propClassString = dr.GetString(0), //for string
propClassInt = dr.GetInt32(1), //for int
propClassDateTime = dr.GetDateTime(2) //for datetime
};
list.Add(value);
}
return list;
After running foreach loop. I am getting NullReferenceException on second item, because query result is null. But I have more item to use on same query and get the result on richTextBox1. so have can I continue the foreach loop if there is any null result.
foreach (string Items in listBox4.Items)
{
using (OracleCommand crtCommand = new OracleCommand("select REGEXP_REPLACE(dbms_metadata.get_ddl('TABLE','" + Items + "'),('" + txtSrcUserID.Text + "...'),'', 1, 0, 'i') from dual", conn1))
{
richTextBox1.AppendText(Environment.NewLine);
richTextBox1.AppendText(crtCommand.ExecuteScalar().ToString() + ";");
richTextBox1.AppendText(Environment.NewLine);
}
}
This is dangerous programming. You really should be checking for the null. Assuming your loop will get bigger.. I would include a continue and make it a bit more obvious what it is you're doing for readability. Omit the continue if you don't need it.
var result = crtCommand.ExecuteScalar();
if (result != null) {
richTextBox1.AppendText(Environment.NewLine);
richTextBox1.AppendText(result.ToString() + ";");
richTextBox1.AppendText(Environment.NewLine);
}
else {
continue;
}
// any other code here.
Change crtCommand.ExecuteScalar().ToString() to (crtCommand.ExecuteScalar() ?? string.Empty).ToString(). This is logically equivalent to:
object dbResult = crtCommand.ExecuteScalar();
if(dbResult == null)
{
richTextBox1.AppendText(";");
}
else
{
richTextBox1.AppendText(dbResult.ToString() + ";");
}
If you want to completely ignore a null result instead of treating it as an empty string, use #SimonWhitehead's code
Recently, I've been getting an IndexOutOfRange exception in a particular method. The new code in this function reads a "csv" file (a .txt file renamed with the extension "CSV") and parses it; so it must be code specific to that or else the data itself that is raising this exception.
But it's apparently not on the Insert into the database, because I added a MessageBox.Show() in the catch block where the insert takes place, and I never see it.
public bool PopulatePlatypusItemsListAndInsertIntoPlatypusItemsTable(frmCentral fc)
{
const int Platypus_ID_OFFSET = 0;
const int Platypus_ITEM_ID_OFFSET = 1;
const int ITEM_ID_OFFSET = 2;
const int PACKSIZE_OFFSET = 3;
bool ret = false;
try
{
string dSQL;
bool First = true;
if (File.Exists(csvFilePathName))
{
int fzz = 0;
dSQL = "DELETE FROM PlatypusItems";
try
{
dbconn.DBCommand(dSQL, true);
}
catch
{
frmCentral.listboxMessage.TopIndex = frmCentral.listboxMessage.Items.Add(Convert.ToString(++frmCentral.lstMessageCount) +
". Error processing PlatypusItem data from server");
}
SqlCeConnection conn = dbconn.GetConnection();
if (conn != null && conn.State == ConnectionState.Closed)
{
conn.Open();
}
SqlCeCommand cmd = conn.CreateCommand();
cmd.CommandText = "INSERT INTO PlatypusItems ( PlatypusID, PlatypusItemID, ItemID, PackSize) VALUES (?, ?, ?, ?)";
if (!ret)
{
ret = true;
}
PlatypusItem DuckbillItm = new PlatypusItem();
string thisLine;
string[] arrLine;
using (StreamReader sr = new StreamReader(csvFilePathName))
{
while (sr.Peek() >= 0)
{
thisLine = sr.ReadLine();
arrLine = thisLine.Split(',');
DuckbillItm.PlatypusID = arrLine[Platypus_ID_OFFSET];
DuckbillItm.PlatypusItemID = arrLine[Platypus_ITEM_ID_OFFSET];
DuckbillItm.ItemID = arrLine[ITEM_ID_OFFSET];
DuckbillItm.PackSize = Convert.ToInt32(arrLine[PACKSIZE_OFFSET]);
PlatypusItemList.List.Add(DuckbillItm);
dSQL = "INSERT INTO PlatypusItems (PlatypusID, PlatypusItemID, ItemID, PackSize) VALUES (" + DuckbillItm.PlatypusID + ",'" +
DuckbillItm.PlatypusItemID + "','" + DuckbillItm.ItemID + "'," + DuckbillItm.PackSize + ")";
if (!First)
{
cmd.Parameters[0].Value = DuckbillItm.PlatypusID;
cmd.Parameters[1].Value = DuckbillItm.PlatypusItemID;
cmd.Parameters[2].Value = DuckbillItm.ItemID;
cmd.Parameters[3].Value = DuckbillItm.PackSize.ToString();
}
if (First)
{
cmd.Parameters.Add("#PlatypusID", DuckbillItm.PlatypusID);
cmd.Parameters.Add("#PlatypusItemID", DuckbillItm.PlatypusItemID);
cmd.Parameters.Add("#ItemID", DuckbillItm.ItemID);
cmd.Parameters.Add("#PackSize", DuckbillItm.PackSize);
cmd.Prepare();
First = false;
}
if (frmCentral.CancelFetchInvDataInProgress)
{
return false;
}
try
{
// testing with these reversed: - either way, get the IndexOutOfRange exception...
//dbconn.DBCommand(cmd, dSQL, true);
dbconn.DBCommand(cmd, cmd.CommandText, true); //<-- If this works as well or better, dSQL is only there for the progress updating code below
// the first line is the legacy code; the second seems more sensible to me; both seem to work
}
catch (Exception x)
{
MessageBox.Show(string.Format("dbcommand exc message = {0}; PlatypusID = {1}; PlatypusItemID = {2}; ItemID = {3}; PackSize = {4}",
x.Message, DuckbillItm.PlatypusID, DuckbillItm.PlatypusItemID, DuckbillItm.ItemID, DuckbillItm.PackSize));//TODO: Remove
frmCentral.listboxMessage.TopIndex =
frmCentral.listboxMessage.Items.Add(Convert.ToString(++frmCentral.lstMessageCount) +
". Error processing Platypus Item data from server");
}
fzz += dSQL.Length; //<-- tried commenting this weird code out, but still get IndexOutOfRangeException
if (fzz > fc.ProgressChangedIndex)
{
fc.ProgressChangedIndex = fzz + fc.ProgressChangedIncrement;
if (((frmCentral.ProgressBar.progressBar1.Maximum/4) + (fzz*3) < frmCentral.ProgressBar.progressBar1.Maximum) &&
((frmCentral.ProgressBar.progressBar1.Maximum/4) + (fzz*3) > frmCentral.ProgressBar.progressBar1.Value))
{
frmCentral.ProgressBar.progressBar1.Value = (frmCentral.ProgressBar.progressBar1.Maximum/4) + (fzz*3);
frmCentral.ProgressBar.progressBar1.Refresh();
}
}
}
}
}
}
catch (Exception ex)
{
duckbilledPlatypiRUs.ExceptionHandler(ex, "PlatypusItemFile.PopulatePlatypusItemsListAndInsertIntoPlatypusItemsTable");
}
return ret;
}
I know this code is kind of a wacko mix of different styles; the good code is mine, and the weird code is legacy (g,d&r)
I can do this, of course, to sweep the dust under the rug:
catch (Exception ex)
{
if (ex.Message.IndexOf("IndexOutOfRange") < 0)
{
duckbilledPlatypiRUs.ExceptionHandler(ex, "PlatypusItemFile.PopulatePlatypusItemsListAndInsertIntoPlatypusItemsTable");
}
}
...but I don't know if that IndexOutOfRangeException is actually something serious that is wreaking mayhem in the innards of this app.
UPDATE
I added this code:
if (arrLine[PLATYPUS_ID_OFFSET].Length > 10) //TODO: Remove?
{
MessageBox.Show(string.Format("PLATYPUS_ID_OFFSET length should be 10; was {0}", arrLine[PLATYPUS_ID_OFFSET].Length));
arrLine[PLATYPUS_ID_OFFSET] = arrLine[PLATYPUS_ID_OFFSET].Substring(0, 10);
}
if (arrLine[PLATYPUS_ITEM_ID_OFFSET].Length > 19)
{
MessageBox.Show(string.Format("PLATYPUS_ITEM_ID_OFFSET length should be 19; was {0}", arrLine[PLATYPUS_ID_OFFSET].Length));
arrLine[PLATYPUS_ITEM_ID_OFFSET] = arrLine[PLATYPUS_ITEM_ID_OFFSET].Substring(0, 19);
}
if (arrLine[ITEM_ID_OFFSET].Length > 19)
{
MessageBox.Show(string.Format("ITEM_ID_OFFSET length should be 19; was {0}", arrLine[PLATYPUS_ID_OFFSET].Length));
arrLine[ITEM_ID_OFFSET] = arrLine[ITEM_ID_OFFSET].Substring(0, 19);
}
...and I never saw those MessageBox.Show()s, so I guess it's not the three string values that are causing the problem; perhaps the int (PackSize). PackSize would never be greater than what Int32 allows; is there a TryParse() equivalent in .NET 1.1?
UPDATE 2
I do see the "IndexOutOfRange" from the exception here, and yet never the MessageBox.Show()s:
try
{
thisLine = sr.ReadLine();
arrLine = thisLine.Split(',');
if (arrLine[PLATYPUS_ID_OFFSET].Length > 10) //TODO: Remove?
{
MessageBox.Show(string.Format("PLATYPUS_ID_OFFSET length should be 10; was {0}", arrLine[PLATYPUS_ID_OFFSET].Length));
arrLine[PLATYPUS_ID_OFFSET] = arrLine[PLATYPUS_ID_OFFSET].Substring(0, 10);
}
. . .
DuckbillItm.PLATYPUSID = arrLine[PLATYPUS_ID_OFFSET];
DuckbillItm.PLATYPUSItemID = arrLine[PLATYPUS_ITEM_ID_OFFSET];
DuckbillItm.ItemID = arrLine[ITEM_ID_OFFSET];
DuckbillItm.PackSize = Convert.ToInt32(arrLine[PACKSIZE_OFFSET]);
}
catch (Exception exc)
{
MessageBox.Show(exc.Message);
}
UPDATE 3
It was bad data, after all; some of the lines had four commas in them instead of the expected three. So, I just removed those lines (after adding code to check each element of the array for size, and trimming them prior to that) and it runs fine.
My initial guess: Probably one of the arrLine[...] lines (e.g. DuckbillItm.PlatypusID = arrLine[Platypus_ID_OFFSET]) would cause this if your input .csv file is bad. Do a debug build and put your breakpoint on the catch handler, and tell us what "ex.StackTrace" says.
I am currently modifying an existing application, I am removing the old UI elements and replacing them with standard WinForms components. So this code is functional as it appears.
My code is passing the conditional IF check when it should not be. The text for each of the comboboxes is <Any> by default, so they should skip past the encapsulated code.
(When filters are selected, they replace the default text to select the correct parts of SQL query to return results)
Now for the bizarre part!
The text property is coming up as System.Data.DataRowView for some of my combobox.text. Originally, this happened for all of them but now the first check appears as <Any> as intended. (Although I didn't change anything at all)
As you can see in this screenshot of my code during debug. The pinned value of cbRegGroup.Text is System.Data.DataRowView but when I enter the list of properties and scroll down to the text property it is shown as <Any>.
I have cleaned and rebuilt my project... and consulted with a college but neither of us can work out why text value is appearing like a .ToString()'ed object.
I am at a loss at what to do next. Any suggestions?
private void LoadPupilView()
{
try
{
this.Cursor = Cursors.WaitCursor;
dgMain.Rows.Clear();
//now populate list view
String filter = "[surname] LIKE '" + SearchString + "%'";
if (!cbYearGroup.Text.Equals("<Any>"))
{
String YearGroupCode = null;
try
{
YearGroupCode = cbYearGroup.SelectedValue.ToString();
}
catch { }
if (!String.IsNullOrEmpty(YearGroupCode))
filter = filter + " AND [yearGroup] LIKE '" + YearGroupCode + "'";
}
if (!cbRegGroup.Text.Equals("<Any>"))
{
String RegGroupCode = null;
try
{
RegGroupCode = cbRegGroup.SelectedValue.ToString();
}
catch { }
if (!String.IsNullOrEmpty(RegGroupCode))
filter = filter + " AND [registrationGroup] LIKE '" + RegGroupCode + "'";
}
if (!cbHouse.Text.Equals("<Any>"))
{
String HouseGroupCode = null;
try
{
HouseGroupCode = cbHouse.SelectedValue.ToString();
}
catch { }
if (!String.IsNullOrEmpty(HouseGroupCode))
filter = filter + " AND [houseGroup] LIKE '" + HouseGroupCode + "'";
}
DataRow[] dataRows = tblPupils.Select(filter);
foreach (DataRow datarow in dataRows)
{
dgMain.Rows.Add(new object[] {
datarow[0].ToString(),
datarow[1].ToString() + " " + datarow[2].ToString(),
datarow[5].ToString(),
datarow[4].ToString(),
datarow[6].ToString(),
datarow[3].ToString()
});
}
}
catch (Exception err)
{
MessageBox.Show("Error : " + err.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
this.Cursor = Cursors.Default;
}
}
I'm very interested in knowing why this seems to be inconsistent... why is the first conditional check passed? When the rest aren't although they are the same.
You need to set the DisplayMember property of the ComboBox to the name of the column you want to display.