How to handle an exception "Specified cast is not valid" - c#

I've made an UltraGrid with Infragistics where I have a column of Datetime type with the format HH:mm.
Normally the column is filled with a value like : "15:13". I can edit it and set what I want then save. But if I delete the field it looks like that : "_ : _" then I save my table, I get back an exception "Specified cast is not valid".
This is because I'm trying to save a value which is not set. I would like to know how to handle this exception.
I tried to compare the fiel to "null" but it does not work.
var newDuration = (DateTime)row.GetCellValue(3);
if (newDuration == null)
{
MessageBox.Show("Please set all the fields.");
}
The dataType of the column is System.DateTime, I set the default value to DB (DBNull) and AllowDBNull is Default.
There are two ways to fix the issue:
display a message to the user to ask him to set a value
If the field is empty, set a default value like 00:00
Ask me if you need more info. Thanks !

Typical pattern to try to get value of wanted type without being sure is
var value = someOtherValue as SomeType;
if (value != null)
{
... // value is a correct SomeType here
}
This works for reference types. In case of structures (DateTime is a structure), which are value types, you'll have to check the type prior
var value = row.GetCellValue(3);
if(value is DateTime)
{
var dateTime = (DateTime)value;
... // dateTime is a valid DateTime here
}
My answer doesn't explain why you have the problem, but shows how to avoid having it (which may not be a good idea, but it seems you want that).
If your value can be DBNull, then simply check for it:
var value = row.GetCellValue(3);
if(value != DBNull.Value)
{
var dateTime = (DateTime)value; // it must work now
...
}

Actually I did this :
try
{
newDuration = (DateTime)row.GetCellValue(3);
}
catch
{
row.SetCellValue(3, new DateTime());
newDuration = (DateTime)row.GetCellValue(3);
}
And it works... Thanks all for your help, I will use what you told in my future dev' !

At the wingrid there is a specific event for handling this errors, its datacellerror quite useful and no need of anything else, hope this its helpfull for someone

Related

C# DateTime Submit method

Can anyone help me to figure out as to why I am getting this error message, when I didn't enter in any date or time when I click the submit button?
An exception of type 'System.InvalidOperationException' occurred in
mscorlib.dll but was not handled in user code Additional information:
Nullable object must have a value.
int result1 = this.startDate.SelectedDate.Value.Date.CompareTo(DateTime.Now.Date);
int result2 = this.endDate.SelectedDate.Value.Date.CompareTo(this.startDate.SelectedDate.Value.Date);
if (result1 >= 0 && result2 > 0)
{
//To Do navigate to sprint dashboard
// var userProjects = new UserStory();
//var sprintDashboardPage = new SprintDashboardPage(usersProjects);
//var mainWindow = this.GetWindow() as MainWindow;
//mainWindow.MainFrame.Navigate(sprintDashboardPage);
this.ErrorMessage = "Date is VALID";
this.CloseWindow();
}
else
{
this.ErrorMessage = "Choose Valid Date";
}
this.startDate.SelectedDate is a Nullable<DateTime>. This means you have to check whether this.startDate.SelectedDate has a value assigned before using it by doing:
if(this.startDate.SelectedDate.HasValue) {
this.startDate.SelectedDate.Value.Date.CompareTo(DateTime.Now.Date);
}
The following will also work:
if(this.startDate.SelectedDate != null) {
this.startDate.SelectedDate.Value.Date.CompareTo(DateTime.Now.Date);
}
Same applies when accessing this.endDate.SelectedDate.
In C#, DateTime is Value Type which means it must always have a value assigned to it. In other words, it can't be set to null. Its default value is DateTime.MinValue. Int32 (or int) is another example of a Value Type and it's default value is 0.
In order to make a Value Type support null, you can wrap it with Nullable<>. Doing so means that you have to explicitly check whether a value has been assigned before accessing the value, or an InvalidOperationException will be thrown.
The DateTime picker control in WPF returns a Nullable<DateTime> object so that you can know whether a user has actually selected a value in the control, as it will be set a non-null value.
You're calling the Value property on a Nullable<> without first checking its HasValue property returns true.
The exception is thrown in the .Value property of the DateTime? (nullable DateTime), as it is required to return a DateTime, but it can't because there's no DateTime to return.
It is a bad idea to access .Value property of Nullable type without checking it. You should consider adding null-checking code. ( e.g. with HasValue property )

How to handle SQL Server NULL values

I'm trying to get values from my database, it works when all columns have values. When a value is NULL, it returns an error.
I've managed to find a way to handle with the strings but if there's an integer I don't know how to handle it. I've tried to find a solution but none has worked for me so far! Here's the code, any help would be highly appreciated.
Thanks!
while (dr.Read())
{
coments comentsar = new coments
{
Id = (int)dr["Id"],
Name = (string)dr["Name"],
Likes = (int)dr["Likes"],
// Signature = dr["Signature"].ToString(),
Datetime = (DateTime)dr["Datetime"]
};
comen.Add(comentsar);
return comen;
}
You can check for null value and if the value is not null assign the variable using ternary operator:
Signature = dr["Signature"] != DBNull.Value ? (string)dr["Signature"] : "No value",
Likes = dr["Likes"] != DBNull.Value ? Convert.ToInt32(dr["Likes"]) : 0,
You need to change your types to Nullable types.
Change (int)dr["Likes"] to (int?)dr["Likes"]
and Datetime = (DateTime)dr["Datetime"] to Datetime = (DateTime?)dr["Datetime"].
You will also need to update your model coments to allow for nullable types.
Microsoft Nullable Types.

C# DateTimeSqlNullValueException: Data is Null

I start MySQL query going to a list with one value that is a DateTime object. As this list builds it hits a null value and --- DateTimeSqlNullValueException: Data is Null.
First I naively tried using ISNULL, !=NULL, ==NULL... which are not methods of the DateTime object. Then I tried
queryResult.EventTime = rdr.GetDateTime("timeIn");
if (Convert.IsDBNull(rdr.GetDateTime("timeIn")))
{
Console.Write("yeup it's null");
queryResult2.EventTime = DateTime.MinValue;
}
This didn't work either.
Then I though instead of rdr.GetDateTime() I thought maybe using GetString() instead and use the methods for strings to test for null then change it back to a DateTime and set it to DateTime.MinValueso I could address it in the view later on. This seemed like a total cludge and not very elegant. So I have been searching for the one liner that I can test the nullness of rdr.GetDateTime("timeIn"); and set it to DateTime.MinValue
Don't use GetDateTime until you know the value isn't null:
if (rdr.IsDBNull(rdr.GetOrdinal("timeIn"))))
{
Console.Write("yeup it's null");
queryResult2.EventTime = DateTime.MinValue;
}
else
{
queryResult.EventTime = rdr.GetDateTime("timeIn");
}
you can write an extension method which will do the check and so make it a one liner (untested code, but should give you the idea):
public static GetDateTimeOrDefault(this IDataReader dr, string columnName, DateTime defaultValue)
{
int ordinal = dr.GetOrdinal(columnName);
if (dr.IsDbNull(ordinal))
{
return defaultValue;
}
return dr.GetDateTime(ordinal);
}
you can then call this like so:
queryResult.EventTime = rdr.GetDateTimeOrDefault("timeIn",DateTime.MinValue);
you don't need to pass in the default value, but its a good idea to do so, as you then have control from the calling site to specify the value you want if the database field is null, and the calling site is where you will know what value you want. you may not always want DateTime.MinValue, you may want DateTime.Now sometimes for example

What is standard way to handle Null dates in .NET

I have asp.net form with C#, where is I am taking user information to insert in the database as usual by using Linq. well. Where as I am taking Date of birth also from the user, but if user skip to fill date text box from ui, then I am getting date like '01/01/0001' something like this, which certainly database security would not allow to store it.
So I need to check somewhere in my code that it is null or in this (above given) format. If it is null or in format '01/01/0001' then what exactly I have to do? I don't have any default
value for dates.
So what is the standard way to handle if date is null (but not mandatory).Please guide me. So many times I found myself in trap while handling null for various types.
Edited
see what i did seems it working here. but i don't think so this is standard way:
DateTime? otxtDOB = new DateTime();
if (!string.IsNullOrEmpty(DOB))
{
if (Convert.ToDateTime(DOB) != DateTime.MinValue)
{
otxtDateOfPurchese = Convert.ToDateTime(Convert.ToDateTime(DOB).ToString("dd-MMM-yyyy"));
}
else
{
otxtDOB = null;
}
}
Please confirm me is this right way ?
Making the date property Nullable (i.e. a "DateTime?") should allow it to actually be null if the user hasn't set it. (And provided your database column will allow nulls, it can be stored as null in the database)
Otherwise it's going to default to DateTime.MinValue which is what you're seeing here. And you'll have to explicity test for DateTime.MinValue when adding to the database.
DateTime is a value type (like a number), so you can't assing a null value to it. Mane people use DateTime.MinValue or DateTime.MaxValue instead, but I prefer to use nullable types:
DateTime? nullableDate;
dateSample.Value = null;
you can do some thing like this C# have some features like nullable type you can make use of
this it will save you some piece of code it will be more robust too.
Public int InsertData(int? ouId)
{
chkValue = ouId.HasValue ? ouId.Value : 0;
}
You have the option of using Nullable<DateTime> (alias DateTime?). This makes you able to handle the date as null throughout your application.
However, personally I am not to found of nullables and would prefer this second path: You can use DateTime.MinValue (which is 01/01/0001) as a meaningful constant in your application and the check for DateTime.MinValue in your data access layer.
The database, if it is an SQL Server and the field is of type smalldatetime, would overflow and throw an exception if you tried to save DateTime.MinValue. Null however, may well be stored in the database for any type.
This is how you can parse your strings into nullable types:
private delegate bool TryParseDelegate<T>(string s, out T t);
private static T? TryParseNullable<T>(string s, TryParseDelegate<T> tryParse) where T : struct
{
if (string.IsNullOrEmpty(s))
return null;
T t;
if(tryParse(s, out t))
return t;
return null;
}
with usage:
var nullableDateTime = TryParseNullable<DateTime>("01/01/0001", DateTime.TryParse);
use
DateTime dt;
if(DateTime.TryParse(DatetImeValue.Tostring(),dt)) // datetimevalue is your db value
{
datetimeproperty = dt; // in your class declare it as DateTime? datetimeproperty
}
else
{
datetimeproperty = null;
}
While displaying check for null, if its null set it empty.
[Update]
Do one thing, Keep the property nullable. In your database. Set field to allow null and in the parameter user #DateTimeParam = null.
OR A QUICK WORKAROUND MAKE THE DATABASE FIELD AND PARAMETER VARCHAR INSTEAD OF DATETIME, IN PARAMETER PASS DATETIMEVALUE.TOSHORTDATESTRING() AND ALSO CHECK IF USER SKIPS
PUT STRING.EMPTY IN PARAMETER. IN THIS MANNER IT WILL BE EASY TO YOU TO DISPLAY DATE AND TIME. YOU NEED NOT CAST OR WIPE OFF THE TIME PART IF YOU DO NOT NEED IT
obj.BirthDate = Convert.ToDateTime(string.IsNullOrEmpty(txtBirthDate.Text.ToString()) ? System.Data.SqlTypes.SqlDateTime.MinValue.Value : Convert.ToDateTime(txtBirthDate.Text.ToString()));
You can use this while passing to database.
object datetimeObj = null;
if (datetimefromUI == DateTime.MinValue) // This is put in the DateTime object by default
datetimeObj = DBNull.Value;
else
datetimeObj = datetimefromUI;
// Post datetimeObj to parameter in database...

not setting date property to object results in error

I have a table that has a smalldatetime NOT NULL field with a default value of getdate(). When creating a new record in the table, I don't set the smalldatetime field in code through LINQ To SQL syntax, I just let the database set the default value which is the current date. If I don't explicitly set it in code, it throws the following error:
SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM.
If I am setting a default in the database, why should I have to set it in code? I have noticed funky things with dates when it comes to LINQ To SQL.
Rather than setting the field as IsDbGenerated, you may want to consider setting its AutoSync value to OnInsert. IsDbGenerated won't let you set the field's value ever (which may be what you want for a "created date" field, but not for a "last modified" field).
However, if you're using an ORM, I would ask you to consider whether you want your application logic in both the database and the application code. Does it make more sense to implement the default value in code (via partial methods like Insert[Entity])?
You have to set the generated property so that LINQ to SQL doesn't send its default value along for creation.
The property is called "Auto Generated Value" on the entity.
To get around this, ensure that your LINQ To SQL model knows that your smalldatetime field is auto-generated by the database.
Select the table's field in your LINQ To SQL diagram, and find the Properties window. Adjust the Auto Generated Value property to True. This will ensure that the field IS NOT included in the INSERT statement generated by LINQ To SQL.
Alternately, you'd have to specify this yourself:
if (newCustomer.DateTimeCreated == null) {
newCustomer.DateTimeCreated = DateTime.Now; // or UtcNow
}
LINQ To SQL does not observe database defaults in a way that you can then subsequently update the value. In order to allow this, you need to set default values in your code.
When creating new objects that are NOT NULL with a database default, C# will use default values, such as MinValue for numbers and dates, empty GUIDs (zeros), etc. You can look for these conditions and replace with your own default value.
This is a known design issue with LINQ To SQL. For an in-depth discussion, see this link:
http://www.codeproject.com/KB/linq/SettingDefaultValues.aspx
Some example code for setting default values in your application:
private void SetDefaults(object LinqObj)
{
// get the properties of the LINQ Object
PropertyInfo[] props = LinqObj.GetType().GetProperties();
// iterate through each property of the class
foreach (PropertyInfo prop in props)
{
// attempt to discover any metadata relating to underlying data columns
try
{
// get any column attributes created by the Linq designer
object[] customAttributes = prop.GetCustomAttributes
(typeof(System.Data.Linq.Mapping.ColumnAttribute), false);
// if the property has an attribute letting us know that
// the underlying column data cannot be null
if (((System.Data.Linq.Mapping.ColumnAttribute)
(customAttributes[0])).DbType.ToLower().IndexOf("not null") != -1)
{
// if the current property is null or Linq has set a date time
// to its default '01/01/0001 00:00:00'
if (prop.GetValue(LinqObj, null) == null || prop.GetValue(LinqObj,
null).ToString() == (new DateTime(1, 1, 1, 0, 0, 0)).ToString())
{
// set the default values here : could re-query the database,
// but would be expensive so just use defaults coded here
switch (prop.PropertyType.ToString())
{
// System.String / NVarchar
case "System.String":
prop.SetValue(LinqObj, String.Empty, null);
break;
case "System.Int32":
case "System.Int64":
case "System.Int16":
prop.SetValue(LinqObj, 0, null);
break;
case "System.DateTime":
prop.SetValue(LinqObj, DateTime.Now, null);
break;
}
}
}
}
catch
{
// could do something here ...
}
}

Categories