C# DateTime Submit method - c#

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 )

Related

C# get property value with reflection has not default value

I have this code:
messageDto = new CorrelationDto()
{
timestamp = default,
};
var isDefault = messageDto.GetType().GetProperty("timestamp").GetValue(messageDto) == default; // FALSE
var isDefault2 = messageDto.timestamp == default; // TRUE
where timestamp is a DateTime.
As you can see, getting the value through reflection and comparing to default return false. Do you have any idea why it's happening and how should I do to check for default values?
Thanks
== EDIT ==
It has been pointed to me that the return value of GetValue() is an object and so it must be casted to DateTime in order for the default to work. Unfortunately I cannot because I'm running this test on all the properties of an object to discover if this object is initialized or not (so I check for null or default value). And the messageDto in reality is a generic type so I don't know the types of its properties a priori.
GetValue returns an object of type object, because it can't know at compile time what the type of the property is. The default value of an object is null, but since DateTime is a value type, its default value cannot be null.
Cast the result of GetValue to DateTime.
If I correctly understood you, this is how I solved this problem:
private static bool IsValueNumericDefault(object value)
{
var intVal = 1;
var doubleVal = 1.0;
return (int.TryParse($"{value}", out intVal) || double.TryParse($"{value}", out doubleVal)) &&
(intVal == default || doubleVal == default);
}
I check random object value through casting it to string and try parse to type that I check. Value parameter is returned by reflection method .GetValue(). You can try to parse it to DateTime or any other type that you check.

LINQ: Nullable object must have a value [duplicate]

There is paradox in the exception description:
Nullable object must have a value (?!)
This is the problem:
I have a DateTimeExtended class,
that has
{
DateTime? MyDataTime;
int? otherdata;
}
and a constructor
DateTimeExtended(DateTimeExtended myNewDT)
{
this.MyDateTime = myNewDT.MyDateTime.Value;
this.otherdata = myNewDT.otherdata;
}
running this code
DateTimeExtended res = new DateTimeExtended(oldDTE);
throws an InvalidOperationException with the message:
Nullable object must have a value.
myNewDT.MyDateTime.Value - is valid and contain a regular DateTime object.
What is the meaning of this message and what am I doing wrong?
Note that oldDTE is not null. I've removed the Value from myNewDT.MyDateTime but the same exception is thrown due to a generated setter.
You should change the line this.MyDateTime = myNewDT.MyDateTime.Value; to just this.MyDateTime = myNewDT.MyDateTime;
The exception you were receiving was thrown in the .Value property of the Nullable DateTime, as it is required to return a DateTime (since that's what the contract for .Value states), but it can't do so because there's no DateTime to return, so it throws an exception.
In general, it is a bad idea to blindly call .Value on a nullable type, unless you have some prior knowledge that that variable MUST contain a value (i.e. through a .HasValue check).
EDIT
Here's the code for DateTimeExtended that does not throw an exception:
class DateTimeExtended
{
public DateTime? MyDateTime;
public int? otherdata;
public DateTimeExtended() { }
public DateTimeExtended(DateTimeExtended other)
{
this.MyDateTime = other.MyDateTime;
this.otherdata = other.otherdata;
}
}
I tested it like this:
DateTimeExtended dt1 = new DateTimeExtended();
DateTimeExtended dt2 = new DateTimeExtended(dt1);
Adding the .Value on other.MyDateTime causes an exception. Removing it gets rid of the exception. I think you're looking in the wrong place.
When using LINQ extension methods (e.g. Select, Where), the lambda function might be converted to SQL that might not behave identically to your C# code. For instance, C#'s short-circuit evaluated && and || are converted to SQL's eager AND and OR. This can cause problems when you're checking for null in your lambda.
Example:
MyEnum? type = null;
Entities.Table.Where(a => type == null ||
a.type == (int)type).ToArray(); // Exception: Nullable object must have a value
Try dropping the .value
DateTimeExtended(DateTimeExtended myNewDT)
{
this.MyDateTime = myNewDT.MyDateTime;
this.otherdata = myNewDT.otherdata;
}
Assign the members directly without the .Value part:
DateTimeExtended(DateTimeExtended myNewDT)
{
this.MyDateTime = myNewDT.MyDateTime;
this.otherdata = myNewDT.otherdata;
}
In this case oldDTE is null, so when you try to access oldDTE.Value the InvalidOperationException is thrown since there is no value. In your example you can simply do:
this.MyDateTime = newDT.MyDateTime;
Looks like oldDTE.MyDateTime was null, so constructor tried to take it's Value - which threw.
I got this message when trying to access values of a null valued object.
sName = myObj.Name;
this will produce error. First you should check if object not null
if(myObj != null)
sName = myObj.Name;
This works.
I got this solution and it is working for me
if (myNewDT.MyDateTime == null)
{
myNewDT.MyDateTime = DateTime.Now();
}

How to handle an exception "Specified cast is not valid"

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

The cast to value type 'Boolean' failed because the materialized value is null

public ActionResult Votation(int id=0)
{
var events = db.Events_Info_tbl.Where(x => x.is_active == true).FirstOrDefault();
//query the first category
List<CampaignManager_tbl> candidates = new List<CampaignManager_tbl>();
candidates = (from cat in db.Events_Category_tbl
join can in db.Candidates_Info_tbl
on cat.events_category_id equals can.events_category_id
where cat.events_info_id == events.events_info_id
select new CampaignManager_tbl {
events_category_name = cat.events_category_name,
candidates_fullname = can.candidates_fullname,
candidates_info_id = can.candidates_info_id,
vote_no = cat.vote_no.Value,
isSelected = can.isSelected.Value,
events_category_id = cat.events_category_id
}).ToList();
return View(candidates);
}
This code was working before but now I've got this error: The cast to value type 'Boolean' failed because the materialized value is null. Either the result type's generic parameter or the query must use a nullable type.
What's wrong with this? I didn't change any of my codes before. It just this time I've got an error.
I ran into this error because of a different problem. In my query I am selecting specific columns from an account member and its associated account:
DBContext.Set<AccountMember>()
.Include(am => am.Account)
.Select(am => new
{
am.ID,
am.IsPrimary,
Account = new { am.Account.ID, am.Account.DoNotEmail }
});
Both of my boolean properties, IsPrimary and DoNotEmail are non-nullable so the resulting property type of their properties in the anonymous type is bool. The exception occurs when an AccountMember does not have an Account. Since am.Account is null, the expression am.Account.DoNotEmail returns null. But the anonymous type's DoNotEmail property inferred it was of type bool which cannot be set to null. The solution is to give it a hint that this should be a nullable bool by casting the property to a bool?:
DBContext.Set<AccountMember>()
.Include(am => am.Account)
.Select(am => new
{
am.ID,
am.IsPrimary,
Account = new { am.Account.ID, DoNotEmail = (bool?)am.Account.DoNotEmail }
});
Hapily EF is smart enough to ignore this cast and not blow up trying to convert it to SQL.
I'm going out on a limb here, but I'd guess it has to do with this line:
isSelected = can.isSelected.Value,
If when the two tables are joined, one of them does not return a value for that particular field, it will be null. It appears the type here is a nullable of some type - probably bool?, based on the naming - and that would match your error.
Try to replace it with the following:
isSelected = can.isSelected.HasValue ? can.isSelected.Value : false,
Of course, you can replace the default false here with true, if that makes more sense in your case.
Edit: Note that you should probably do the same for the other column you use in a similar way (I'm assuming this is returning an int?):
vote_no = cat.vote_no.HasValue ? cat.vote_no.Value : 0
Is db.Candidates_Info_tbl.IsSelected a bit field?
If so, the query could likely result in
isSelected = can.isSelected.Value,
with isSelected being null, whereas you probably declared isSelected as bool in CampaignManager_tbl class.
Change the isSelected to bool in the CampaignManager_tbl class and try again.
if your field type is int while some value is null, then you can use case-when and convert to bit like below
SELECT CASE WHEN FieldName IS NOT NULL THEN CONVERT(BIT,FieldName) ELSE CONVERT(BIT,0) END AS NewFieldName

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...

Categories