Check if child object value exists NullReferenceException - c#

I'm pretty new to C#. While attempting to set a local variable value, I'm running into a NullReferenceException.
It appears that the Buyer object is null, which I'm assuming is why it can't figure out the Buyer.Username value. What I'm not sure about is how to check if Buyer is not null AND that the Buyer.Username has a non-null value (in the most simple way possible). Unfortunately, I'm using C# 7.3 which doesn't appear to have support for the ?? operator.
BuyerUserName = string.IsNullOrEmpty(model.Transactions[i].Buyer.Username) ? "" : model.Transactions[i].Buyer.Username

Both ?? and ?. were introduced in C# 6, so you can use them:
BuyerUserName = model.Transactions[i].Buyer?.Username ?? string.Empty;
But even without that, there is nothing wrong with taking more than one line to do something, and you could just use an if statement:
var buyer = model.Transactions[i].Buyer;
if (buyer != null && buyer.Username != null)
BuyerUserName = buyer.Username;
else
BuyerUserName = string.Empty;

Related

Handling null returns in new linq objects c#

What I'm going for? I need to post a newly created object to a db, the incoming object may have a null value. The created object is set to #nullible true where needed.
When data comes in and I land on a null string in my object I get a null reference and land on catch.
My code:
Objects.Data.Info.StoredData postData = new Objects.Data.Info.StoredData
{
Name = data.data.Name,
Type = data.data.Type,
Price = data.data.Price,
Indicator = data.data.Indicator,
Scan = data.data.Scan,
Comment = data.data.Extra
};
db.Information.Add(postData);
db.SaveChanges();
data.data.Extra can be null, sometimes.
I would usually write if statements to counter this, but don't feel like it's the best practice here. What direction should I go? I've checked a few other questions and msdn and can't find a clear path.
Thanks.
You can succinctly default to an empty string when the property is null by using the ?? operator, like so:
Comment = data.data.Extra ?? ""
//the value on the right is used if the expression on the left is null
?? is called the 'null-coalescing' operator: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-coalescing-operator
If you also want to handle the intermediate properties being null (which I don't think applies to this case but is good to know), and still want to default to an empty string, you can combine this with Eugene's suggestion of using ?. like so:
Comment = data?.data?.Extra ?? ""
?. is called the 'null-conditional' operator: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/member-access-operators#null-conditional-operators--and-
var postData = new Objects.Data.Info.StoredData
{
Name = data.data.Name,
Type = data.data.Type,
Price = data.data?.Price,
Indicator = data.data.Indicator,
Scan = data.data.Scan,
Comment = data.data.Extra
};
db.Entry(postData).State=EntityState.Added;
db.SaveChanges();
I thought that you have facing difficulty with Price attribute because this one is Not null in your db once your programming cursor over there it failed, so once you exactly do what I did then eventually you change this nullable and then easily check or insert on runtime.
You should use the Null Conditional Operator (?.), like this:
data?.data?.Name
This will prevent an NullReferenceException if data or data.data is null.

Checking for null values in quickbooks using QBFC

I am trying to get the list of items inside of a quickbooks database. I have the following snippet of code:
IItemServiceRet itemServiceRet = itemRet.ItemServiceRet;
TestItem item = new TestItem();
item.Name = itemServiceRet.Name.GetValue();
item.Desc = itemServiceRet.ORSalesPurchase.SalesOrPurchase.Desc.GetValue();
item.Rate = itemServiceRet.ORSalesPurchase.SalesOrPurchase.ORPrice.Price.GetValue().ToString();
item.ItemType = "Service";
item.QBID = itemServiceRet.ListID.GetValue();
item.EditSeq = itemServiceRet.EditSequence.GetValue();
The code fails on the line:
item.Desc = itemServiceRet.ORSalesPurchase.SalesOrPurchase.Desc.GetValue();
"Object reference not set to an instance of an object"
Because that particular service item in the QB database does not have a description. I was curious if there was a 'clean' way to check for null values without having to have each line include an if statement checking if GetValue() returns null?
Edit: After trying Andrew Cooper's solution of:
item.Desc = itemServiceRet.ORSalesPurchase.SalesOrPurchase.Desc == null ? null : itemServiceRet.ORSalesPurchase.SalesOrPurchase.Desc.GetValue();
It still throws the exception:
Object reference not set to an instance of an object
Its as if GetValue() returns nothing at all if there is no description, which wouldn't make much sense.
You could use the ternary operator like this:
item.Desc = itemServiceRet.ORSalesPurchase.SalesOrPurchase.Desc == null ? null : itemServiceRet.ORSalesPurchase.SalesOrPurchase.Desc.GetValue();
But that's pretty ugly.
Best bet is to create a helper method that takes whatever type Desc and wraps the above logic.
I don't think there's any better solution, as you can't access the functions of a null object. I typically create a constructor for my items that does the checking so I only have to do that once. So in your example:
TestItem item = new TestItem(itemRet.ItemServiceRet);
The constructor would look like this:
public TestItem(IItemServiceRet i)
{
if(i.Name != null) this.Name = i.Name.GetValue();
if(i.ORSalesPurchase != null)
if(i.ORSalesPurchase.SalesOrPurchase != null)
{
if(i.ORSalesPurchase.SalesOrPurchase.Desc != null) this.Desc = i.ORSalesPurchase.SalesOrPurchase.Desc.GetValue();
if(i.ORSalesPurchase.SalesOrPurchase.ORPrice != null)
if(i.ORSalesPurchase.SalesOrPurchase.ORPrice.Price != null) this.Price = i.ORSalesPurchase.SalesOrPurchase.ORPrice.Price.GetValue();
}
}Keep in mind that this does work well for strings, as an empty string is usually the same as a blank field, but for number fields in QuickBooks this may cause problems. For example, an Invoice line can have a blank quantity field (which is a double). A double will default to the value of 0.0, but a blank quantity field in QuickBooks is treated as a quantity of 1.0. This can also cause problems with dates, as QuickBooks can have null date fields.

Lightswitch NullReferenceException for String in C#

I am sure this is a case of basic ignorance, but I'm trying to test a database value using code behind in a Lightswitch project.
I'm checking if a varchar(MAX) value is null
if (Order.OrderNotes.Equals(null))
{
do.something...
}
However, I get a NullReferenceException if the value is null. If a value is there I get no error. I've tried using .contains(null), .Length = 0, .ToString() = "" etc without luck. It seems that ints and dates work fine using Equals(null), but not it seems for a string.
Help!!
Assuming you're calling this from a details screen where Order != null as #DeeMac pointed out.
You can check that Order isn't null using the same code below :
if (Order.OrderNotes == null)
{
// do.something...
}
if OrderNotes is null, you can't call any method, properties or whatever using that instance
you should call
if (Order.OrderNotes == null)
of course I assume that the var Order is not itself null,
if you want to be absolutely sure you could change your test in this way
if (Order != null && Order.OrderNotes == null)
In LightSwitch, to test if a nullable property has a value or not, you can use HasValue, so:
"if Order.OrderNotes.HasValue"
If you want the value if there is one, or the default value for the property type, you can use GetValueOrDefault:
"var value = Order.OrderNotes.GetValueOrDefault"
I agree wholeheartedly with Steve that you should be doing null checking on objects (such as Order) before trying to get a value from any of that object's properties.

C# coalesce operator Throws

I have a class with a string property. I use the coalesce operator when reading from it as it might be null, but it still throws me an NullRefrenceExeption.
string name = user.Section.ParentSection.Name ?? string.Empty;
To be more specific, its the ".ParentSection" that's null so is it because it don't even have ".name" ? If that's the case should i test ".ParentSection" first with an if block?
I assume there are something about the Coalesce operator i dont understand, hope someone can shed some light on whats going wrong here.
To be more specific, its the ".ParentSection" that's null so is it
because it don't even have ".name" ?
Yes.
If that's the case should i test ".ParentSection" first with an if
block?
Yes.
You'll need to check if Section and ParentSection are null. You could use an if-statement for this or write an extension method like this:
public static class MaybeMonad
{
public static TOut With<TIn, TOut>(this TIn input, Func<TIn, TOut> evaluator)
where TIn : class
where TOut : class
{
if (input == null)
{
return null;
}
else
{
return evaluator(input);
}
}
}
You would use this method like so:
string name = user.With(u => u.Section)
.With(s => s.ParentSection)
.With(p => p.Name) ?? string.Empty;
I think it's a lot cleaner than an if-statement with a lot of &&.
Some further reading: http://www.codeproject.com/Articles/109026/Chained-null-checks-and-the-Maybe-monad
You need to check if user, user.Section, or user.Section.ParentSection are null before you can use the null coalescing operator on a property of user.Section.ParentSection.
Nested property access is not safe if any of the objects accessed are null this will throw a NullReferenceException. You will have to explicitly test for the outer objects to be not null.
E.g.:
string name = string.Empty;
if(user!=null && user.Section!=null && user.Section.ParentSection !=null)
name = user.Section.ParentSection.Name ?? string.Empty;
In general I would try to avoid nested access to properties, you are violating the Law of Demeter. Some refactoring might make this unnecessary in the first place.
The ?? operator checks if the left side is null and if so returns the right one, if not the left one.
In your case the left-side is the "Name" property in the object user.Section.ParentSection and this is null.
In those cases either think on what might be null or do something like this:
string name = user == null
|| user.Section == null
|| user.ParentSection == null
|| user.Section.ParentSection.Name == null
? string.Empty
: user.Section.ParentSection.Name;
(yeah it's ugly I know)
Chances are user or user.Section or user.Section.ParentSection is a null value.
The ?? operator doesn't prevent checks like:
if (user != null && user.Section != null && user.Section.ParentSection != null){
Make sure that everything up to the string property is valid and exists, then you can use ??. You can't call (null).Name, no matter how many times you try.
Yes you need to check if Section or ParentSection are null before you check Name
It is probably best to do something like this:
if(user!=null && user.Section!=null && user.Section.ParentSection!=null)
{
string name = user.Section.ParentSection.Name ?? string.Empty;
}
The null coalescing operator takes a statement like:
a = b ?? c;
What this says is "evaluate b; if it has a non-null value then assign that to a. Otherwise assign the value of c to a".
However within your b you're using a user object which may be null that has a section object that may be null that has a parent section property that may be null that had a name property that may be null. If you wanted to check all of these (and typically you should) then you can do something like:
string name = string.Empty;
if (user != null &&
user.Section != null &&
user.Section.ParentSection != null)
{
name = user.Section.ParentSection.Name ?? string.Empty;
}
As soon as the IF check fails it will not check further and therefore you don't get a NullReferenceException when you assume an object is present and then try to access one of its properties.

how can I check whether the session is exist or with empty value or null in .net c#

Does anyone know how can I check whether a session is empty or null in .net c# web-applications?
Example:
I have the following code:
ixCardType.SelectedValue = Session["ixCardType"].ToString();
It's always display me error for Session["ixCardType"] (error message: Object reference not set to an instance of an object). Anyway I can check the session before go to the .ToString() ??
Something as simple as an 'if' should work.
if(Session["ixCardType"] != null)
ixCardType.SelectedValue = Session["ixCardType"].ToString();
Or something like this if you want the empty string when the session value is null:
ixCardType.SelectedValue = Session["ixCardType"] == null? "" : Session["ixCardType"].ToString();
Cast the object using the as operator, which returns null if the value fails to cast to the desired class type, or if it's null itself.
string value = Session["ixCardType"] as string;
if (String.IsNullOrEmpty(value))
{
// null or empty
}
You can assign the result to a variable, and test it for null/empty prior to calling ToString():
var cardType = Session["ixCardType"];
if (cardType != null)
{
ixCardType.SelectedValue = cardType.ToString();
}

Categories