converting string to datetime in C# on null value exception - c#

I use the below code
extensionRequest[i].EndDate = DateTime.Parse(dsResult.Tables[0].Rows[i]["ActualEndDate"].ToString());
extensionRequest[i].ExtendedEndDate = DateTime.Parse(dsResult.Tables[0].Rows[i]["ExtendedEndDate"].ToString());
extensionRequest[i].ReceivedDate =Convert.ToDateTime(dsResult.Tables[0].Rows[i]["dReceivedOn"].ToString());
this works fine when values are coming from the DB
but when NULL values are returned it throws an exception!!
Should i check values for all three values like the code below
if (dsResult.Tables[0].Rows[i]["dReceivedOn"].ToString()==null){
extensionRequest[i].ReceivedDate="";
}
else{
extensionRequest[i].ReceivedDate =Convert.ToDateTime(dsResult.Tables[0].Rows[i]["dReceivedOn"].ToString());
}
or i should assign all dates to null on exception?!
is there any other way to do in single line? like tryparse or something?

I'll try being creative. You can create a Nullable TryParse as an Extension Method edition:
public static DateTime? TryParseNullable(this DateTime dateTime, string val)
{
DateTime outValue;
return DateTime.TryParse(val, out outValue) ? (DateTime?) outValue : null;
}
and then use:
extensionRequest[i].EndDate = DateTime.TryParseNullable(dsResult.Tables[0].Rows[i]["ActualEndDate"].ToString());
and that can be your one liner.

You can use DateTime.TryParse() method which returns true on successfull conversion otherwise returns false.
Note: calling ToString() on null throw NullReferenceException hence you need to check for null value before conversion.
Try This:
if(dsResult.Tables[0].Rows[i]["ActualEndDate"] != null)
DateTime.TryParse(dsResult.Tables[0].Rows[i]["ActualEndDate"].ToString(),
out extensionRequest[i].EndDate);

You can check if value is null like this
extensionRequest[i].EndDate = Convert.IsDbNull(dsResult.Tables[0].Rows[i]["ActualEndDate"]) ? null : Convert.ToDateTime(dsResult.Tables[0].Rows[i]["ActualEndDate"]);
I'm sure .ToString() is not required.
It will be more readable if you cache a row to the local variable:
var row = dsResult.Tables[0].Rows[i];
...
extensionRequest[i].EndDate = Convert.IsDbNull(row["ActualEndDate"]) ? null : Convert.ToDateTime(row["ActualEndDate"]);
Be sure .EndDate and others allow null values. In other words, that is DateTime?

Related

C# Null Conditional Operator with nullable datetime

I am trying to learn use the null conditional operator but can't seem to get it to work,
string datetest = DOInfolist[i].RentalItem.SimCard.DateIn[u].Value.ToShortDateString() ?? "Empty";
DateIn is a list of nullable DateTime (List<Datetime?>) .
I did debugging and all the values in DateIn[u] give null.
What am I doing wrong?
If all the values in the DateIn array are null, your code would throw a NullReferenceException.
You may use the null-propagation-operator here:
string datetest = DOInfolist[i].RentalItem.SimCard.DateIn[u]?.ToShortDateString() ?? "Empty";
This operator (?.) now returns a nullable string. If DateIn[u] has a value, ToShortDateString() is called and the operator returns a nullable string with the returned value.
If DateIn[u] is null the operator returns null, too.
You have a mistake. First check for null values by HasValue and use single ? not double ?? like the following snippet:
string datetest = DOInfolist[i].RentalItem.SimCard.DateIn[u].HasValue ? DOInfolist[i].RentalItem.SimCard.DateIn[u].ToShortDateString() : "Empty";

How are null values in C# string interpolation handled?

In C# 6.0, string interpolations are added.
string myString = $"Value is {someValue}";
How are null values handled in the above example? (if someValue is null)
EDIT:
Just to clarify, I have tested and am aware that it didn't fail, the question was opened to identify whether there are any cases to be aware of, where I'd have to check for nulls before using string interpolation.
That's just the same as string.Format("Value is {0}", someValue) which will check for a null reference and replace it with an empty string. It will however throw an exception if you actually pass null like this string.Format("Value is {0}", null). However in the case of $"Value is {null}" that null is set to an argument first and will not throw.
From TryRoslyn, it's decompiled as;
string arg = null;
string.Format("Value is {0}", arg);
and String.Format will use empty string for null values. In The Format method in brief section;
If the value of the argument is null, the format item is replaced with
String.Empty.
It seems that the behavior depends on which underlying formatting methods are called, and the implementation of these can change over time. If you get a null formated into the string such as "(null)", it is not sure this will stay the same over several years. In some newer version of .NET it can start throwing an exception.
So I think the most safe approach is to make some condition to avoid using the null. Write a simple ternary operation like:
int? someValue = 5;
var valueStr = (someValue is not null) ? someValue.ToString() : string.Empty;
var myString = $"Value is {valueStr}";
It is an extra line of code, but at least the behavior is controlled.

Compare string null or empty in c#

In my table of MySQL Db I have the field Check.
The value memorized on the field Check it could be : null or -1.
When the value memorized on the field Check is null or -1 I need in return the xxx value. and I have tried :
string Check = sdr["Check"] == DBNull.Value || sdr["Check"] == "-1,00" ? "xxx" : sdr["Check"].ToString();
Without success because the output is always -1,00.
How to do resolve this?
Please help me, thank you so much in advance.
The problem is that you are comparing the wrong objects. The values returned from System.Data result sets are wrappers around the actual value. What you want are the typed versions. Basically, the check should look like this:
int checkIndex = sdr.GetOrdinal("Check");
string Check = sdr.IsDBNull(checkIndex) || (sdr.GetString(checkIndex) == "-1,00") ? "xxx" : sdr.GetString(checkIndex);
If you "Check" is actually a number, you may want to use the IntValue("Check") call, just to deal with globalization issues if your app is ever deployed where they use a "." instead of a "," for your decimal point.
See https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldatareader(v=vs.110).aspx for the full API.
If your MySQL database is not set to use the same locale formatting as your C# application, your assumptions about number formats could be incorrect. To make a more robust version of your check, I would recommend something like this:
int checkIndex = sdr.GetOrdinal("Check");
string Check = "xxx";
double checkValue = sdr.IsDBNull(checkIndex) ? -1 : Convert.ToDouble(sdr[checkIndex]);
if (checkValue != -1)
{
Check = checkValue.ToString(CultureInfo.CurrentCulture);
}
If the data type is decimal 10,2 you need Convert.ToDecimal the value :
string Check = (sdr["Check"] == DBNull.Value || Convert.ToDecimal(sdr["Check"]) == -1) ? "xxx" : sdr["Check"].ToString();
You can compare a string empty or null by below code
string str = Your string
if(String.IsNullOrEmpty(str))
{
if yes, it comes here
}
else
{
if not, it comes here
}
The String.IsNullOrEmpty() is a bool type.

Nullable dateTime without losing methods

I've made a method to convert a datetime object to a date-only format. In order to access it, I have to assign the value of my parameter to the value that will be in a datatable. The obvious method would thus be to add a ? after the DateTime object to make it nullable, however this removes it's methods (or at least, the one I need to use), making my method worthless.
string dateWithOutTime(DateTime? datetime)
{
string reply = datetime.Date.ToString();
return reply;
}
usage:
string str = dateWithOutTime(*DataSet*.*DataTable[n]*.Rows[n][n] as DateTime?);
Is there a way to accomplish this without adding any extra objects?
Note: a star (*) denotes a variable type/object
DateTime? doesn't have the same methods as DateTime, they're different types. You have to retrieve the actual datetime value using DateTime?'s Value property:
string dateWithOutTime(DateTime? datetime)
{
if(datetime.HasValue)
return datetime.Value.Date.ToString();
else
return //...
}
Read the documentation for Nullable<T> here.
Unless I misunderstand your problem, I'd say you need to check if your DateTime? parameter is null or not. If it is, return an empty string (or a string you want to display for missing dates). If it isn't, you can use the Value property:
string dateWithOutTime(DateTime? datetime)
{
return datetime.HasValue ? datetime.Value.Date.ToString() : String.Empty;
}
Update
If you only want the date-part in your string and you want it to be culture-sensitive, you can use ToShortDateString() instead of ToString(). You can even leave out the Date property:
string dateWithOutTime(DateTime? datetime)
{
return datetime.HasValue
? datetime.Value.ToShortDateString()
: String.Empty;
}

How do I convert a database number to hex when the field might be null?

I have trouble to convert from decimal to hex.
Here is my code:
select new
{
MessageID = table1.Field<Int32?>("MessageID"),
MessageIDHex = (String)table1.Field<Int32>("MessageID").ToString("X")
}
It gives me Error
with DBNUll.Value cant not change to System.In32
So I have tried
MessageIDHex= (String)table1.Field<Int32?>("MessageID").ToString("X")}
but it gives me another error.
How can I fix it or it does have another way to solve it.
Apparently, MessageID can be DBNull. The simplest solution is to read the value as a nullable int (to prevent the conversion error from occurring). If you use Field with a nullable type, DBNull is automatically converted to null, which can then be coerced to 0 with the ?? operator:
MessageIDHex = (table1.Field<Int32?>("MessageID") ?? 0).ToString("X")
Alternatively, if you prefer, you can have DBNull values in the database result in an empty or a null string for MessageIDHex:
MessageIDHex = table1.IsNull("MessageID") ? "" : table1.Field<Int32>("MessageID").ToString("X")
MessageIDHex = table1.IsNull("MessageID") ? null : table1.Field<Int32>("MessageID").ToString("X")

Categories