how to check JsonObject has null value(windows.data.json) - c#

How can I check if any key from json object have null value
JsonObject itemObject = itemValue.GetObject();
string id = itemObject["id"].GetString() == null ? "" : itemObject["id"].GetString();
this is my code but app crashes on it if null value for key "id"

IJsonValue idValue = itemObject.GetNamedValue("id");
if ( idValue.ValueType == JsonValueType.Null)
{
// is Null
}
else if (idValue.ValueType == JsonValueType.String)
{
string id = idValue.GetString();
}
If you do this too much, consider adding extension methods.
To do the opposite use:
IJsonValue value = JsonValue.CreateNullValue();
Read here more about null values.

http://msdn.microsoft.com/en-us/library/ms173224.aspx
The ?? operator is called the null-coalescing operator. It returns the left-hand operand if the operand is not null; otherwise it returns the right hand operand.

if itemObject["id"] is null then the method null.GetString() doesn't exist and you'll get the error specified (null object never has any methods/fields/properties).
string id = itemObject["id"] == null ? (string)null : itemObject["id"].GetString(); // (string)null is an alternative to "", both are valid null representations for a string, but you should use whichever is your preference consistently to avoid errors further down the line
the above avoids calling .GetString() until you've asserted that the ID isn't null (check here for more in-depth), if you're using C#6 you should be able to use the new shorthand:
string id = itemObject["id"]?.GetString();

Here is solution for the issue
string id = itemObject["id"].ValueType == JsonValueType.Null ? "" : itemObject["id"].GetString();

Related

TryGetValue on a null dictionary

I am trying to use TryGetValue on a Dictionary as usual, like this code below:
Response.Context.Skills[MAIN_SKILL].UserDefined.TryGetValue("action", out var actionObj)
My problem is the dictionary itself might be null. I could simply use a "?." before UserDefined but then I receive the error:
"cannot implicitly convert type 'bool?' to 'bool'"
What is the best way I can handle this situation? Do I have to check if UserDefined is null before using TryGetValue? Because if I had to use Response.Context.Skills[MAIN_SKILL].UserDefined twice my code could look a little messy:
if (watsonResponse.Context.Skills[MAIN_SKILL].UserDefined != null &&
watsonResponse.Context.Skills[MAIN_SKILL].UserDefined.TryGetValue("action", out var actionObj))
{
var actionName = (string)actionObj;
}
Add a null check (?? operator) after the bool? expression:
var dictionary = watsonResponse.Context.Skills[MAIN_SKILL].UserDefined;
if (dictionary?.TryGetValue("action", out var actionObj)??false)
{
var actionName = (string)actionObj;
}
Another option is to compare to true.
It looks slightly weird, but it works with three-valued logic and says: is this value true but not false or null
if (watsonResponse.Context.Skills[MAIN_SKILL]
.UserDefined?.TryGetValue("action", out var actionObj) == true)
{
var actionName = (string)actionObj;
}
You can do the opposite logic with != true: is this value not true, so either false or null
if (watsonResponse.Context.Skills[MAIN_SKILL]
.UserDefined?.TryGetValue("action", out var actionObj) != true)
{
var actionName = (string)actionObj;
}

Accessing null value leads to application fail / C#

I'm just looping and appending my properties to a big string:
output.Append(property.GetValue(this).ToString()));
When app breaks in that moment property represent a ProductNumber which is a string, value of this is Product object which has value of ProductNumber = null, so I've tried something like this:
output.Append(property.GetValue(this)?.ToString()));
But anyway it breaks..
How could I improve this code to avoid breaking there?
Thanks
Cheers
It seems that output.Append complains on null values. There are 2 possible sources of pesky nulls here:
property.GetValue(this) returns null and thus ?. in ?.ToString() propagates null
ToString() itself returns null (hardly a case, but still possible)
We can solve both possibilities with ?? operator: let's return an empty string whatever the source of null is:
property.GetValue(this)?.ToString() ?? ""
Final code is
output.Append(property.GetValue(this)?.ToString() ?? "");
This code:
output.Append(property.GetValue(this)?.ToString()));
Is the same as:
object propValue = property.GetValue(this);
string propString = null;
if (propValue != null)
{
propString = propValue.ToString();
}
output.Append(propString); // propString can be null
This can be simplyfied like so:
string propString = property.GetValue(this)?.ToString(); // This performs a ToString if property.GetValue() is not null, otherwise propString will be null as well
output.Append(propValue); // propValue can be null
If you want to prevent calling Append with a null value you can do:
string propString = property.GetValue(this)?.ToString(); // This performs a ToString if property.GetValue() is not null, otherwise propString will be null as well
if (propString == null)
{
propString = string.Empty;
}
output.Append(propValue); // propString is not null
This can be simplified with the null-coalescing operator:
string propString = property.GetValue(this)?.ToString() ?? string.Empty
output.Append(propValue); // propString is not null

Shorthand to cast a string value

I'm not talking about javascript, but in javascript, I can declare a string like this:
var identity = {
getUserId: function () {
return 'userid';
}
};
var userid = identity.getUserId() || '';
That means: if identity.getUserId() is null or undefined, the value '' will be casted to userid automatically.
Now, in C#:
public static void AddOnlineUser(this IIdentity identity)
{
string userid = identity.GetUserId();
// long way to check userid is null or not:
if (string.IsNullOrEmpty(userid))
{
userid = "";
}
// invalid C# syntax:
// Operator || cannot be applied to operands of type 'string' and 'string'
// string userid = idenity.GetUserId() || "";
// Only assignment, call, increment, decrement, and new object expressions can be used as a statement
// string.IsNullOrEmpty(userid) ? "" : userid;
}
I don't mean: want to create a C# variable same as javascript syntax. But in this case, is there a way to cast value "" to userid if it's null or empty in 1 line?
The Null Coalescing Operator ??
C# has it's own null-coalescing operator ?? to do this to handle null values :
// This will use the available GetUserId() value if available, otherwise the empty string
var userid = identity.GetUserId() ?? "";
Keep in mind this operator will only work as expected if the first value in your statement is null, otherwise it will use that value. If there is a chance that this isn't the case (and you might encounter a non-null invalid value), then you should consider using a ternary operator instead.
The Ternary Operator ?:
Otherwise, you could use a ternary operator ?: (i.e. an inline if-statement) to perform this check as well. This is similar to the example you provided, however it's worth noting that you need to actually set userid to the result :
// This will set it to empty string if null or empty, otherwise it will use the returned id
userid = String.IsNullOrEmpty(userid) ? "" : userid;

How to return a null value from a database

I am trying to populate a combobox with a list my query returns. When I execute my program it gives me a specified cast is not valid error ( I have it execute on page load event). Every field in the database I have to work with can be null except the primary key. So I tried using DBNull.Value but it can't get my (int)reader fields to work. I have supplied my code below for a better understanding. How can I get my (int)reader's to work with my statements, so they can read when there is a null value?
CustData cd = new CustData();
cd.CustomerID = (int)reader["CustomerID"];
cd.Name = reader["Name"] != DBNull.Value ? reader["Name"].ToString() : string.Empty;
cd.ShippingAddress = reader["ShippingAddress"] != DBNull.Value ? reader["ShippingAddress"].ToString() : string.Empty;
cd.ShippingCity = reader["ShippingCity"] != DBNull.Value ? reader["ShippingCity"].ToString() : string.Empty;
cd.ShippingState = reader["ShippingState"] != DBNull.Value ? reader["ShippingState"].ToString() : string.Empty;
cd.ShippingZip = (int)reader["ShippingZip"];
cd.BillingAddress = reader["BillingAddress"] != DBNull.Value ? reader["BillingAddress"].ToString() : string.Empty;
cd.BillingCity = reader["BillingCity"] != DBNull.Value ? reader["BillingCity"].ToString() : string.Empty;
cd.BillingState = reader["BillingState"] != DBNull.Value ? reader["BillingState"].ToString() : string.Empty;
cd.BillingZip = (int)reader["BillingZip"];
cd.Territory = reader["Territory"] != DBNull.Value ? reader["Territory"].ToString() : string.Empty;
cd.Category = reader["Category"] != DBNull.Value ? reader["Category"].ToString() : string.Emptyy
That is because int is not nullable. You need to use int? or nullable<int> (long hand) to allow it to be an int OR a null value.
You can then use the usual .HasValue and .Value etc to get the value from the item.
EDIT: To enhance the visibility of my comment to this answer. I would advise against checking for NULL and storing Zero into your property because then when you save back you are changing a Null to a Zero even though nothing has been changed by the system. Now, reports etc may distinguish between NULL and Zero (very often) and could start doing strange things!
Null does NOT equal zero!! If you assume it does as a work around... What happens if I truly do want to record zero? How do you differentiate between a real zero and a "was null now zero" trick? Do it right, save yourself the pain!
Use nullable int, or just make your control for your int's too
reader["ShippingZip"] != DBNull.Value ? (int)reader["ShippingZip"] : default(int);
You should use a nullable int for your variable and cast it, like (int?). Int can only have a value; nullable types can also be null. When you use a nullable type, you can look at the property .HasValue. Here is the MSDN page: http://msdn.microsoft.com/en-us/library/2cf62fcy.aspx

Why ?: operator does not work with nullable<int> assignation?

I'm creating an object for my database and I found a weird thing, which I don't understand:
I've an object which should reference a "language" by an ID, but this can be null, so my property is a int?(Nullable<int>)
so firstly I tried to use the object initializer:
myObject = new MyObject()
{
myNullableProperty = language == null ? null : language.id;
}
but it doesn't work! It tell me that null cannot be converted to int
But if I it in a if/else structure, I can put null in a var and then assign it to my properties.
Why is this acting like this?
You may try casting the null to int? as the ?: operator requires both operands to return the same type:
myNullableProperty = language == null ? (int?)null : language.id
This is because of a type mismatch. You must cast your null value to the int type.
The reason is, when using the ? operator the left and the right side of the : are required to be from the same type and typeof(null)!=typeof(int) so:
myNullableProperty = language == null ? (int?)null : language.id;
Most likely null is interpreted as object which obviously can't be assigned to int. You might want to use myNullableProperty = language == null ? (int?)null : language.id;

Categories

Resources