Why does this simple string formating now throw exception? - vb.net

I'm using Authorize.net API and they require card expiration field to be formated as "yyyy-mm". We did that with this simple line of code:
expirationDate = model.Year.ToString("D4") & "-" & model.Month.ToString("D2")
and this absolutelly worked. I still have cards stored in the system that were saved using this method! But today I was testing something completelly unrelated, and wanted to add another card, and bam, this code exploded with this exception:
System.InvalidCastException: 'Conversion from string "D4" to type 'Integer' is not valid.'
Inner exception to that one is:
Input string was not in a correct format.
This just... doesn't make sense to me. Why in the world is it trying to convert format specifier (D4) into an integer? What input string? What in the world changed in two days?

The problem is that your are using a Nullable(Of Integer). This is a different structure that does not support the overloads of the ToString method a normal Integer has.
You can view the overloads of the Nullable structure here.
I suggest you use the GetValueOrDefault() method to get the proper Integer and also apply the value you expect in case the value is Nothing.
If it is impossible that a instance with a Nothing set for the year reaches this method you can simply use the Value property.
I still do not fully understand why you get this strange error message. Maybe you could check out what the actual method that is called is? Pointing at the method should give you that information. It can't be Nullable(Of Integer).ToString

Well, I found a workable solution and something of an answer thanks to #Nitram's comment. The type of Year/Month property has been changed from Integer to Integer?. Obviously, this isn't a very satisfying answer because I still don't understand why the nullable int can't be formatted, and yet the code compiles perfectly. The working solution for me has been using static format method on String as so:
expirationDate = String.Format("{0:D4}-{1:D2}", model.Year, model.Month)
This works fine even with nullable types.

Related

InvalidCastException on Passing Object as Nullable Int64 [duplicate]

This question already has answers here:
Why does (int)(object)10m throw "Specified cast is not valid" exception?
(4 answers)
Closed 2 years ago.
Okay, so I'm no stranger to coding and this strikes me as absolutely silly. Maybe someone can shed some light on why this is failing as usually VB.Net is intuitive and flexible with this type (pun intended) of thing?
I have a simple example, where I want to pass an object set with an integer value of lets say 6 to a procedure with a nullable Int64 parameter. I'd like to do so as I can't change the incoming value from object, it is a property of a class and may very well be nothing, hence the nullable Int64 being used.
Private Sub NullableParamTest(ByVal ID As Int64?)
MsgBox(ID)
End Sub
Now a simple sample like this will cause the exception:
Dim objTest As Object = 6
NullableParamTest(objTest)
Why is this not being boxed properly when the object is being set to an integer and passing to a procedure with an Int64? type? If I wrap the objTest with CInt(objTest) and cast it first it's fine, but I shouldn't need to do that at least in VB. I have logging methods that optionally take in various IDs as Int64? but the source is this Object property causing it to fail...even though they have perfectly valid Int64s set.
I wanted to avoid the whole Optional...Int64 = Nothing as that's not really setting it to nothing, granted it works as my IDs would never be zero but it's not true to what is really going on.
Thanks to the comments from #GSerg, it appears the following is the answer to this question found here:
A boxed value can only be unboxed to a variable of the exact same type.
It links to another answer describing this behavior as being performance related. In short you have to convert/cast the value within the object first before passing it.
In my case my passed value of an ID would never be 0 so using a regular Int64 and checking that it's nothing would work, otherwise using Object for a type is the alternative as wrapping all of the method calls with over half a dozen converts would be hideous.
The other comment by #GSerg mentions the notation of adding an & after the value to make it an explicit Int64, also allowing it to work in this case. Note that casting the value in this way as an Int32, which in theory would work (as it fits within an Int64 space), in fact does not due to the first part of my comment that it has to be unboxed as the exact same value type for the parameter.

Change a setting using a combobox in vb.net

I'm working on a program, and I need to be able to change a setting using a combobox. I'm getting
CS0266 Cannot implicitly convert type 'object' to 'FastColoredTextBoxNS.Language'. An explict conversion exists (are you missing a cast?)
Using the code:
{
fastColoredTextBox1.Language = comboBox1.SelectedItem
}
Does anyone know a simple way to fix this? If any more info is needed, I will gladly edit it in.
You must cast to the desired type, since the SelectedItem property returns the unspecific type Object.
fastColoredTextBox1.Language = DirectCast(comboBox1.SelectedItem, FastColoredTextBoxNS.Language)
Note there is also the CType function. In addition to performing type casts it also performs also type conversions. We do not need a conversion here, if the items in the ComboBox are of the required type. DirectCast just means, okay I know that the item with the runtime type Object is of the required type, just take it as such.
See also:
Casting DataTypes with DirectCast, CType, TryCast
Difference between DirectCast() and CType() in VB.NET

VB.NET LINQ Method Syntax disallows implicit conversions from 'Integer?' to 'Integer'

Compare weirdness when working with LINQ and Entity Framework.
I want to retrieve an ID from my DB and I get this weird message.
I could simply fix it as you can see but I want to understand why this happens.
Question:
Why do I get this error message even if I check with "HasValue" or I use "FirstOrDefault"? It can't be null in my opinion but I obviously miss something.
Add .Value if you are 100% sure the Integer? has a value.
Why do I get this error message even if I check with "HasValue"
Entity Framework just uses the objects you give it. It can't create a new object where OPX_ isn't nullable.
the setOpxRights function presumably takes an Integer as a parameter and Option Strict On won't allow an Integer? to be implicitly converted to an Integer. If you are sure that it will always have a value, pass in cctUser.OPX_Rechte.Value
The compiler is not perfect, we can see that OPX_Rechte will have a value because of the where statment, but for the compiler you are just using a the object cctUser that have an Integer? and it needs an Integer.

How to get checked state of Checked Listbox vb.net

I have a checked listbox which I am running through and saving names to a database. As I run through I need to see if the check box is checked or clear.
I've tried the following code but to no avail:
If chklbRegister.GetItemCheckState(nLoop).ToString = "1" Then
.Parameters.AddWithValue("#sqlAttended", 1)
Else
.Parameters.AddWithValue("#sqlAttended", 0)
End If
I have also tried:
If chklbRegister.GetItemCheckState(nLoop) = True Then
but it still doesn't worked. Ideas please.
Thanks
Graham
GetItemCheckState returns an Enum. An enum is not a string and not a boolean.
You should test again the defined values of the enum
If chklbRegister.GetItemCheckState(nLoop) = CheckState.Checked Then
-----
If you apply the ToString method to an enum value you get the translated text of the enum, in your case the word "Checked" and not the string "1".
Of course, being the enums fundamentally numeric values of integral type you could always cast the return value to an integer, but you never should do it and use instead the proper Enum syntax
As a final note. This problem should have been signaled by the compiler and not slipped past the compilation phase. This compiler behavior is caused by the Option Strict set to Off instead of On. I suggest to change this option in the configuration of your project to avoid other errors of this kind that could be very subtle.
You can see for the documentation for GetItemCheckState that it returns a value from the CheckState enumeration so you need to check this:
chklbRegister.GetItemCheckState(nLoop) = CheckState.Checked

Nullable (of date) things to consider when converting

I have been asked to find out why an ajax call doest work if date fields are left blank on a web form, finding out was easy, its because the VB function expects an object with a Date type.
I'm going to convert these values to Nullable(Of Date), but I'm reluctant as this is a class that's quite heavily used and I don't want to break anything else.
My thinking however is that everything calling this class must be sending in a correct Date or it would throw an error currently, so I should be ok.
As long as I check for a value using HasValue and get the date out using Value then I shouldn't have any problems, or is there something else I need to consider?
If you change every reference to use the Date's Value property it will be no worse than what you have now. Then you can add the HasValue checks where you need to.