NullReferenceException in string.IsNullOrWhiteSpace() and string.IsNullOrEmpty() - c#

I'm checking the cell values of cells of a column that might or not be empty/null so I needed something to avoid a NullReferenceException.
How do I do that since even with the IsNullOrWhiteSpace() and IsNullOrEmpty() I get that exception somehow.
Here's part of the code I'm using:
s = "Total = " + dataGridView1.Rows[0].Cells.Count +
"0 = " + dataGridView1.Rows[0].Cells[0].Value.ToString() +
"/n 1 = " + dataGridView1.Rows[0].Cells[1].Value.ToString() +
"/n 2= " + dataGridView1.Rows[0].Cells[2].Value.ToString() +
"/n 3 = " + dataGridView1.Rows[0].Cells[3].Value.ToString() +
"/n 4= " + dataGridView1.Rows[0].Cells[4].Value.ToString() +
"/n 5 = " + dataGridView1.Rows[0].Cells[5].Value.ToString() +
"/n 6= " + dataGridView1.Rows[0].Cells[6].Value.ToString() +
"/n 7 = " + dataGridView1.Rows[0].Cells[7].Value.ToString();
if (string.IsNullOrEmpty(dataGridView1.Rows[0].Cells[8].Value.ToString()))
{
}
else
{
s += "/n 8 = " + dataGridView1.Rows[0].Cells[8].Value.ToString();
}
I've tried those methods I've tried putting it ==null, I've tried !=null. What else is there or what am I doing wrong exactly and how do I do it right?

the are a lot of places you code could throw that exception ..
dataGridView1.Rows[0] //here
.Cells[0] //here
.Value //and here
.ToString()
I belive you don't need the ToString() just type:
"... "+ dataGridView1.Rows[0].Cells[0].Value
in your ifstatement do this:
if (string.IsNullOrEmpty(dataGridView1.Rows[0].Cells[8].Value as string))

Many people don't understand how to diagnose a NullReferenceException. Consider the following:
dataGridView1.Rows[0].Cells[3].Value.ToString()
Many parts of this could be null. It's the same thing as
var a = dataGridView1.Rows;
var b = a[0];
var c = b.Cells;
var d = c[3];
var e = d.Value;
var f = e.ToString();
If a is null, then a[0] will throw a NullReferenceException. If b is null, then b.Cells will throw a NullReferenceException, etc.
You simply have to figure out which of these is null in your particular situation. The simplest way is to use the debugger. Set a breakpoint before the line that throws the exception. Then hover the mouse over various parts of the expression to see which are null, or use the "Watch" window to enter parts of the expression.
When you find a null, you can stop looking for your NullReferenceException.

You can add an extra line of code to check and handle the null case.
var value = dataGridView1.Rows[0].Cells[0].Value;
string s = (value == null ? string.Empty : value.ToString());
If value is null, then ToString() will not be evaluated and the program cannot throw NullReferenceException.

I think in dataGridView1.Rows[0].Cells[8].Value.ToString() you will get a NullReferenceException if the Value is null. So you should check for dataGridView1.Rows[0].Cells[8].Value != null and then you can convert it to a string

Related

How do i working with Arrays in a While loop?

I have tried to wipe this data while trying to export a database into my program.
The basic problem is that I do not know why he can not use LIKE in my SQL statement.
So I wanted to catch all DataRows and write them into an array, which I can edit later.
The program throws an exception:
Error message: System.IndexOutOfRangeException: "The index was outside the array area."
If I did something unusual or wrong in my Post I sincerely apologies, this is my first entry in this forum.
Code:
public void TestQuery()
{
string file = #"C:\Users\Michael\Downloads\7z1900-x64.msi";
// Get the type of the Windows Installer object
Type installerType = Type.GetTypeFromProgID("WindowsInstaller.Installer");
// Create the Windows Installer object
WindowsInstaller.Installer installer = (WindowsInstaller.Installer)Activator.CreateInstance(installerType);
// Open the MSI database in the input file
Database database = installer.OpenDatabase(file, 0);
// Open a view on the Property table for the version property
View view = database.OpenView("SELECT * FROM `File`");
// Execute the view query
view.Execute(null);
// Get the record from the view
Record record = view.Fetch();
int i = 1;
string[] sreturns = new string[60];
while (record != null)
{
Console.WriteLine("Ausgabe: " + record.get_StringData(0) + '=' + record.get_StringData(1) + '=' + record.get_StringData(2) + '=' + record.get_StringData(3));
record = view.Fetch();
sreturns[i] = record.get_StringData(0).ToString();
i++;
}
}
First thing I see is that you're starting at 1, while (C#) arrays are 0-based.
In you screenshot I see that i is 60, so that would be the problem. Index 60 doesn't actually exist in your array, as it goes from 0 to 59.
You can add i < sreturns.Length to make sure you are in the array range.
Also, make sure you start with i = 0 and not 1.
int i = 0;
string[] sreturns = new string[60];
while (record != null && i < sreturns.Length)
{
Console.WriteLine("Ausgabe: " + record.get_StringData(0) + '=' + record.get_StringData(1) + '=' + record.get_StringData(2) + '=' + record.get_StringData(3));
record = view.Fetch();
sreturns[i] = record.get_StringData(0).ToString();
i++;
}
Why not using a list instead of an array?
List<string> sreturns = new List<string>();
while (record != null)
{
try
{
Console.WriteLine("Ausgabe: " + record.get_StringData(0) + '=' + record.get_StringData(1) + '=' + record.get_StringData(2) + '=' + record.get_StringData(3));
record = view.Fetch();
var result = record.get_StringData(0);
sreturns.Add(result.ToString());
}
catch (Exception e)
{
Console.WriteLine("No record...");
}
}
This way you dont need to worry about the array size - its maintainable -efficient - and if in the future the size change you don't have to worry about it.
List documentation here
What is the query with LIKE that you have tried? The following should work:
SELECT * FROM File WHERE FileName LIKE '%.exe' OR FileName LIKE '%.msi'
EDIT: On further investigation (https://learn.microsoft.com/en-us/windows/win32/msi/sql-syntax), the documentation seems to imply that the LIKE operator is not supported. But you could start off with an IS NOT NULL and do more complex filtering in the loop, like you're doing.
EDIT 2, expanding on Alex Leo's answer.
List<string> sreturns = new List<string>();
while (record != null)
{
Console.WriteLine("Ausgabe: " + record.get_StringData(0) + '=' + record.get_StringData(1) + '=' + record.get_StringData(2) + '=' + record.get_StringData(3));
var result = record.get_StringData(0);
if(!string.IsNullOrWhiteSpace(result) && (result.EndsWith(".exe") || result.EndsWith(".msi")))
{
sreturns.Add(result.ToString());
}
record = view.Fetch();
}
Note that the view.Fetch() inside the while loop has been moved to the end, or you would skip the first record, as well as get another null reference when the last record has already been read, but the while loop executes one more time.

If a field contains null then entire concatenate result is null

I am trying to concatenate for a label. If a field contains null then entire concatenate result is null.
[HttpGet]
public ActionResult PMAByPC(string PartnerCode)
{
var result = (from N in _POSContext.PMAs
where (N.PartnerCode == PartnerCode)
select new
{
label = N.Address1 + " | " + N.Address2 + " | " + N.City,
id = N.ID
});
return Json(result);
}
Here, if data is not present in of the fields, label becomes null.
I tried with
select new { label = N.Address1 ?? "?" + " | " + N.Address2 ?? "?" + " | " + N.City ?? "?", id = N.ID }
then it takes only N.Address1 value and ignores the rest of the fields.
Looks like this is a standard SQL string concatenation behavior (the same happens with SqlServer database).
If you want to evaluate the concatenation server side (database), you need to convert null to empty string "" (or something else) using the ?? operator. Similar to your attempt, but you've missed the C# operator precedence. The way you wrote it is equivalent of
N.Address1 ??
(
("?" + " | " + N.Address2) ??
(
("?" + " | " + N.City) ?? "?"
)
)
which is not what was the intent.
You can avoid such issues by enclosing similar conversions with brackets:
select new
{
label = (N.Address1 ?? "?") + " | " + (N.Address2 ?? "?") + " | " + (N.City ?? "?"),
id = N.ID,
}
This is the standard compliant and reasonable behavior: if you concatenate a string with an unknown string, the result is unknown.
Use the coalesce function for that:
coalesce(col1, '') || coalesce(col2, '')

Object not set to an instance of an object in sql query, null reference exception

In this specific case I am getting null reference exception, and I cant solve it.
public class Tiket
{
private Korisnik korisnik;
public Korisnik Korisnik
{
get { if (korisnik == null)
{
korisnik = new Korisnik();
}
return korisnik; }
set { korisnik = value; }
}
}
Inside form I am taking value inserted in textbox and sending it to method which deal with database(its much more complex but I am trying to make it simple):
Tiket t = new Tiket();
t.Korisnik.Ime = txtImeKorisnika.Text;
thatMethod(t);
So above, I am not getting null reference exception while assigning value to t.Korisnik.Ime, but Inside method I am getting one:
string upit = "SELECT * FROM " + Tiket + " " + " WHERE " + t.Korisnik.Ime;
extra question connected to this topic:
I am having same problem while trying to add values to these fields from database which are also class properties inside Tiket.
tikeet.Korisnik.JMBG = red[5].ToString();
tikeet.Radnik.SifraRadnika = Convert.ToInt32(red[6]);
I know why is this happening but I dont know how to initialize Korisnik, Radnik here.
EDIT: I hope this helps now, so You can help me !
I have client server app and I am sending Tiket to Server..than its sent as OpstiDomenskiObjekat(instead of Tiket) to method I have problem now.
OpstiDomenskiObjekat is interface, so I could have one or few methods for many similar things I need.
public List<OpstiDomenskiObjekat> vratiZaUslovJedanPlus(OpstiDomenskiObjekat odo)
{
string upit = "SELECT * FROM " + odo.tabela + " " + " WHERE " + odo.uslovJedan;
OleDbDataReader citac = null;
OleDbCommand komanda = new OleDbCommand(upit, konekcija, transakcija);
try
{
citac = komanda.ExecuteReader(); // **here is exception thrown**
DataTable tabela = new DataTable();
tabela.Load(citac);
List<OpstiDomenskiObjekat> lista = new List<OpstiDomenskiObjekat>();
foreach (DataRow red in tabela.Rows)
{
OpstiDomenskiObjekat pom = odo.napuni(red);
lista.Add(pom);
}
return lista;
}
catch (Exception ex)
{
throw ex;
}
//this is implementation in class Tiket
public string uslovJedan
{
get
{
return Korisnik.Ime;
}
}
//this should happen after method, I will have List as I needed
List<Tiket> lista = Broker.dajSesiju().vratiZaUslovJedanPlus(odo).OfType<Tiket>().ToList<Tiket>();
return lista;
Connection, transaction etc.. its all somewhere else, but It all works, I promise :)
The + operator in this case is a string concatenation operator. Ticket is the name of your class and its not clear whether you have a property with that same name. If you do have a property by that name,
string upit = "SELECT * FROM " + Tiket + " " + " WHERE " + t.Korisnik.Ime;
it is possible that the above line is failing because the Tiket property is null. And also, it's ToString() might not be valid for the FROM clause of a query.
Update
As you can see, it didn't compile for me at all. When I wrote a property with the same name. It compiled, and constructed the string, inserting a null character where Ticket was.
The second screenshot shows what happens if it was a property.
Your string is still constructed in that case and you will get an invalid query at the line string upit = "SELECT * FROM " + Tiket + " " + " WHERE " + t.Korisnik.Ime; which is probably causing your issues. Please update with a screenshot of where the exception is being thrown.

c# concatenate List<string> plus string

I have this List in c#:
List<string> cad_analise = new List<string>();
And I added this:
cad_analise.Add("FQ");
cad_analise.Add("CR");
So, I would like to do this
var joinstring = "";
joinstring = cad_analise[0] + ", second is " + cad_analise[1] + ", join the words.";
But, I am getting the following error:
Index was out of range. Must be non-negative and less than the size of the collection.
I did some tests here and I fought that the error is when I join the cad_analise[0] and cad_analise[1].
See here the error: https://dotnetfiddle.net/3rowFv
Here is working perfectly: https://dotnetfiddle.net/G6JwFs
In your code example https://dotnetfiddle.net/3rowFv you'll have these bools:
bool has_analiseCR = true;
bool has_analiseFQ = true;
bool has_analisePCB = false;
bool has_analise2FAL = false;
bool has_analiseGP = false;
Then you are checking if it's true add a value to has_analise List<string> if false add it to cad_analise List<string>. So in the end:
has_analise will look like:
[0] => "CR"
[1] => "FQ"
then you are trying on line 74:
print_analise_cad = "AnĂ¡lise " + has_analise[0] + ", " + has_analise[1] + " e " + has_analise[2] + " do equipamento " + NumSerie_app + " e amostra de " + data_amostra + " foram cadastradas.";
Where you are calling has_analise[2] this index does not exits as shown above.
The list only has a value on index [0] and [1] and not on [2]
Also you are checking on number_analise_cad if (number_analise_cad == 3) and not on the length of number_analise_existente whits is based on the lenght of has_analise List<string>
This is the reason why you are getting the index out of range exception.
As you can verify here, your (as posted in the question) code works.
The only issue I found is a missing semicolon at the end of the last line (but I guess this was a copy/paste error):
joinstring = cad_analise[0] + ", second is " + cad_analise[1] + ", join the words.";

How to get same functionality as ISNULL in LINQ query

I have been trying to find a solution for this since part few hours and I feel like my brain is about to help. I have the below LINQ query.
DropDownListItem item = (
from c in context.Practitioners
where c.PractitionerID == id
select new DropDownListItem
{
Id = c.PractitionerID,
DisplayValue = c.FirstName + " " + c.MiddleName + " " + c.LastName,
IsActive = c.IsActive,
DisplayOrder = c.PractitionerID,
CreatedById = new Guid("COFFEEOO-LOVE-LIFE-LOVE-C0FFEEC0FFEE"),
CreatedDate = c.CreatedDate,
}).FirstOrDefault() ?? new DropDownListItem();
response.Data = item;
There are instaces when c.MiddleName could be null. How Can I handle it in this query so that if c.MiddleName is null I can just assign a blank "" string to it ?
Here's what I tried already which did not work out.
- Created extension to check IsNullOrEmpty. I found out this does not work on LINQ queries.
- tried converting c.Middle to string by doing something like c.MiddleName.ToString() which did not work for LINQ query either.
Please give me more more direction as to which I should move toward. Thanks!
You can check for nulls and empty strings instead of using any methods that LINQ to Entities does not understand (Trim will be translated to SQL):
DisplayValue = c.FirstName + " " + ((c.MiddleName == null || c.MiddleName.Trim() == string.Empty) ? string.Empty : (c.MiddleName + " ")) + c.LastName,
I'm a bit confused about your question. You are making a string, so even if c.MiddleName is null it should be interpreted as an empty string.
You can also try this:
DisplayValue = (c.MiddleName != null) ?
c.FirstName + " " + c.MiddleName + " " + c.LastName :
c.FirstName + " " + c.LastName,
But pretty much all other answers are very similar.
As a note, you are missing brackets behind select new DropDownListItem, so that might be problem.
I'll assume what you mean by c.MiddleName is empty is that c.MiddleName is null (because if it's an empty string you question makes no sense :p).
If it is indeed the case try writing c.MiddleName ?? ""
This means that if the left part of ?? is null the use the right part of the expression
See https://msdn.microsoft.com/en-us/library/ms173224.aspx for more documentation
And you would have to change your code in this fashion :
DropDownListItem item = (
from c in context.Practitioners
where c.PractitionerID == id
select new DropDownListItem
{
Id = c.PractitionerID,
DisplayValue = (c.FirstName ?? "") + " " + (c.MiddleName ?? "") + " " + (c.LastName ?? ""),
IsActive = c.IsActive,
DisplayOrder = c.PractitionerID,
CreatedById = new Guid("COFFEEOO-LOVE-LIFE-LOVE-C0FFEEC0FFEE"),
CreatedDate = c.CreatedDate,
}).FirstOrDefault() ?? new DropDownListItem();
response.Data = item;
To be noted that the ?? operator have one of the lowest priorities in C#.
Check the operators priority in C# here https://msdn.microsoft.com/en-us/library/6a71f45d.aspx
try this
DisplayValue = (c.FirstName?? string.Empty) + " " + (c.MiddleName ?? string.Empty) + " " + (c.LastName?? string.Empty)

Categories

Resources