ASP.NET Error with session key strings - asp.net

Hey I am trying to convert the following code to VB.NET from this webpage
http://msdn.microsoft.com/en-us/magazine/cc163730.aspx
And have a method converted as such
' Get the order from the session on demand
Private Shared Function GetOrderFromSession(ByVal i As Integer) As ShoppingCartOrder
Dim session As HttpSessionState = HttpContext.Current.Session
Dim ID As Integer = 0
Dim quantity As Integer = 0
' note: For simplicity session key strings are dynamically
' created——for performance reasons they should be precreated.
ID = CInt(session(ShoppingCartItemIDKeyBase + i))
quantity = CInt(session(ShoppingCartOrderQuantityKeyBase + i))
Dim item As ShoppingCartItem = ShoppingCartItem.GetItem(ID)
Return New ShoppingCartOrder(item, quantity)
End Function
But getting the error around the lines
ID = CInt(session(ShoppingCartItemIDKeyBase + i))
quantity = CInt(session(ShoppingCartOrderQuantityKeyBase + i))
Error 1 Overload resolution failed because no accessible 'Item' can be called without a narrowing conversion:
'Public Default Property Item(index As Integer) As Object': Argument matching parameter 'index' narrows from 'Double' to 'Integer'.
'Public Default Property Item(name As String) As Object': Argument matching parameter 'name' narrows from 'Double' to 'String'.

The + operator can be used for string concatenation as well as the & operator in VB.NET, but the ampersand is the preferred operator.
Just to be sure, can you switch them to ampersands and see if the error still occurs? ShoppingCarItemIDKeyBase is a string, and I'm not sure if the + operator forces the strings to convert to numbers since the user has the option of using &.
ID = CInt(session(ShoppingCartItemIDKeyBase & i))
quantity = CInt(session(ShoppingCartOrderQuantityKeyBase & i))

One or both of these variables is a decimal type rather than an integer:
ShoppingCartItemIDKeyBase
ShoppingCartOrderQuantityKeyBase

Related

How to have a value of NULL for DateTime?

In my SQL database, I've declared DpsDate and AdmDate as DATE, also I've set them to allow nulls. When I run my application and leave these columns blank, I get this error:
Failed to convert parameter value from a String to a DateTime.
This is where I'm a bit confused because I've set them to allow nulls so shouldn't the database accept no value? The application works if I set both dates to "01/01/1900". I've tried setting them to "00/00/0000" but I get the same error.
Here's what I have:
If tbNotifyDate.Text = "" Then
cmd.Parameters.Add("#DpsDate", SqlDbType.Date, 50).Value = "01/01/1900"
Else
cmd.Parameters.Add("#DpsDate", SqlDbType.Date, 50).Value = tbNotifyDate.Text
End If
If tbAdmDate.Text = "" Then
cmd.Parameters.Add("#AdmDate", SqlDbType.Date, 50).Value = "01/01/1900"
Else
cmd.Parameters.Add("#AdmDate", SqlDbType.Date, 50).Value = tbAdmDate.Text
End If
You need to use DBNull.Value to represent NULL in ADO.NET. Things like table adapters and Entity Framework, which are built on top of ADO.NET, can support nullable value types and thus use Nothing to represent NULL but ADO.NET itself predates nullable value types, so Microsoft had to invent a type specifically for the purpose of representing NULL.
I would suggest using the If operator to make the code more concise:
Dim value As Date
cmd.Parameters.Add("#AdmDate", SqlDbType.Date).Value = If(Date.TryParse(tbAdmDate.Text, value),
value,
CObj(DBNull.Value))
The CObj is required because the two possible results of If must be the same type and Date and DBNull are not the same type. By casting one possible result as type Object, they are both interpreted as type Object and the compiler is happy.
Note that, as I have written that example, this will save NULL if the TextBox contains anything that isn't a valid representation of a Date. You can use whatever validation is appropriate in your specific case or, if you've already validated, just check for an empty TextBox and use CDate.

error when tried to delete empty rows from datatable

I tried this LINQ code to delete empty rows from datatable
NewDt = NewDt.Rows.Cast(Of DataRow)().
Where(Function(row) Not row.ItemArray.All(Function(field) TypeOf field Is System.DBNull OrElse String.Compare(TryCast(field, String).Trim(), String.Empty) = 0)).CopyToDataTable()
But it showing error
Lambda parameter 'row' hides a variable in an enclosing block, a previously defined range variable, or an implicitly declared variable in a query expression.
Any idea?
Yes - read the error message. You've already got a variable called row in your method, so you need to choose a different name for the parameter in the lambda expression. For example:
NewDt = NewDt.Rows.Cast(Of DataRow)().
Where(Function(x) Not x.ItemArray.All(
Function(field) TypeOf field Is System.DBNull _
OrElse TryCast(field, String).Trim() = "").
CopyToDataTable()

Conversion failed when converting the varchar value '[]' to data type int

I'm trying to create a search function that uses a TextBox and two DropDownLists to return entries from my MSSQL DB. The way I have it set up is by passing the search queries via QueryStrings to a GridView on a separate page. Here's what I have for the search function:
Partial Class Includes_LeftCol
Inherits System.Web.UI.UserControl
Public Sub btnSearch_Click(sender As Object, e As System.EventArgs) Handles btnSearch.Click
Dim SelectURLRangePrice As String
If tbxSearch.Text.Length = 0 And ddlRangeName.SelectedValue = "" And ddlPriceRange.SelectedValue = "" Then
SelectURLRangePrice = "SearchResults.aspx"
Response.Redirect(SelectURLRangePrice)
ElseIf tbxSearch.Text.Length = 0 And ddlRangeName.SelectedValue = "" And ddlPriceRange.SelectedValue.Length > 0 Then
SelectURLRangePrice = "SearchResults.aspx?price=" & ddlPriceRange.Text
Response.Redirect(SelectURLRangePrice)
ElseIf tbxSearch.Text.Length = 0 And ddlRangeName.SelectedValue.Length > 0 And ddlPriceRange.SelectedValue.Length > 0 Then
SelectURLRangePrice = "SearchResults.aspx?range=" & ddlRangeName.Text & "&price=" & ddlPriceRange.Text
Response.Redirect(SelectURLRangePrice)
End If
Dim SelectURLRange As String
If tbxSearch.Text.Length = 0 And ddlRangeName.SelectedValue.Length = 0 Then
SelectURLRange = "SearchResults.aspx"
Response.Redirect(SelectURLRange)
ElseIf tbxSearch.Text.Length = 0 And ddlRangeName.SelectedValue.Length > 0 Then
SelectURLRange = "SearchResults.aspx?range=" & ddlRangeName.Text
Response.Redirect(SelectURLRange)
End If
Dim SelectURL As String
If tbxSearch.Text.Length = 0 Then
SelectURL = "SearchResults.aspx"
Response.Redirect(SelectURL)
ElseIf tbxSearch.Text.Length > 0 Then
SelectURL = "SearchResults.aspx?search=" & tbxSearch.Text
Response.Redirect(SelectURL)
End If
End Sub
End Class
And here's my SQL statement:
SELECT Product_Rental, Product_ID, Range_Name, Model_Name, Product_Name, Product_Year, Product_Code, Product_Active, Product_DateAdded
FROM Products
WHERE (Range_Name LIKE '%' + #Range_Name + '%') OR
(Model_Name LIKE '%' + #Model_Name + '%') OR
(Product_Name LIKE '%' + #Product_Name + '%') OR
(Product_Code LIKE '%' + #Product_Code + '%') OR
(Product_Year LIKE '%' + #Product_Year + '%') OR
(Product_Rental BETWEEN #Product_Rental AND #Product_Rental + 50)
Once submitted, I get the following error:
Conversion failed when converting the varchar value '[e.g. 209.35]' to data type int.
I'm a beginner at this so apologies if it's something stupid, and I've tried to go as far as I can before posting, but I just can't get past this.
Thanks in advance.
The problem is here:
Product_Rental BETWEEN #Product_Rental AND #Product_Rental + 50
Because you are using + 50 data type precedence kicks in. The docs state:
When an operator combines two expressions of different data types, the rules for data type precedence specify that the data type with the lower precedence is converted to the data type with the higher precedence. If the conversion is not a supported implicit conversion, an error is returned. When both operand expressions have the same data type, the result of the operation has that data type.
So internally SQL Server attempts to convert #Product_Rental to an int (because 50 is an int, and an int has a higher precedence than varchar). So whenever This can reproduced fairly simply:
DECLARE #Var VARCHAR(6) = '50';
SELECT *
FROM (VALUES (1)) T (A)
WHERE A < #Var + 50;
Then checking the execution plan XML we can see the comversion behind the scenes:
<ScalarOperator ScalarString="(1)<(CONVERT_IMPLICIT(int,[#Var],0)+(50))">
This basically shows that SQL Server has essentially turned
A < #Var + 50
Into
A < CONVERT(INT, #Var) + 50;
This is fine if #Var converts to an int, but if it has a decimal point it will not, as can be shown by:
SELECT CONVERT(INT, '50.0');
I would suggest if your column Product_Rental contains decimal data, then it should be of the decimal type, as should any parameters used to filter the column.
The SQL Type INT is for whole numbers (1,2,3). FLOAT could support decimals. And text characters like [ and ] definitely won't work with an INT column.
Edit from Comments:
Since the Product_Rental field is VarChar try changing to this (if you don't want to change the type on the table, which I recommend):
--Make #Product_Rental a numeric type first.
(CAST(Product_Rental AS FLOAT) BETWEEN #Product_Rental AND #Product_Rental + 50)
The problem is here:
Product_Rental BETWEEN #Product_Rental AND #Product_Rental + 50
You've got operands of multiple types there. One of them is an integer. SQL Server is trying to convert everything to an integer, so they can all be compared meaningfully, apples to apples (why does it pick integer? Precedence rules). It can't do that in this case, because in SQL you can't implicitly convert a varchar with a decimal point to an integer. Information will be lost there, so it won't just do that automatically for you. If you really wanted all integers, you would have to convert to float, then implicitly truncate the float to an integer. Better would be to convert everything here to a float up front, because you do actually want to be comparing floats here. If you do that, SQL Server won't be left floundering around guessing what data type you want.
So, if the varchar values have decimal points, you will get an error that resembles the one you gave us, but it won't have square brackets in it. (PLEASE don't insert random characters into error messages and tell people that's what SQL Server gave you, if it isn't).
Try this:
convert(float,Product_Rental)
BETWEEN convert(float,#Product_Rental)
AND convert(float,#Product_Rental) + 50
This is why you should use the correct data types in your table and in your variables. Both should have been decimal or float all along.
If the actual value in your variable, or in either of those fields, is '[e.g. 209.35]', that can't be converted to float anyhow.

Database result is passed as null unless it's read

Set rslistings = my_conn.Execute(strSQL)
Do while NOT rslistings.Eof
description = strip(rslistings("description"))
rslistings.MoveNext
loop
In strip - NULL is being passed. However, if I attach a debugger and inspect the contents of rslistings("description"), then the actual Field object is passed through
It's quite old asp code, but it works on IIS6, just not IIS7
EDIT This only happens on the "description" field with is a text type (MySQL database)
strip doesn't do a lot:
If NOT IsNull(passedinvalue) Then
// do something
Else
// do something else
If I call strip like strip(rs("description")), it is never null as the Field object is passed in. If I assign it to another value, then pass it in (like strip(mynewvar)) then the correct value is passed in.
Edit - database bits as requested below
Set my_conn = Server.CreateObject("ADODB.Connection")
Set rs = Server.CreateObject("ADODB.Recordset")
my_conn.Open "DSN=mydb"
SQL
Set rs = my_conn.Execute("SELECT description FROM table")
the Field Collection is the default member of the Recordset object.
so is the value property for the Field object.
so the following two code statements are equivalent.
Debug.Print objRs.Fields.Item(0) ' Both statements print
Debug.Print objRs(0) ' the Value of Item(0).
it is a difference if you assign a value to a variable or use it as a parameter in a function.
#Paul: If strip doesn't check if description is NULL before working on it, you could do this --
Do while NOT rslistings.Eof
description = rslistings("description")
If NOT IsNull(description) Then
description = strip(description)
Else
description = "" ' or you could have description = " "
' if you output to screen later on
End If
rslistings.MoveNext
loop

vb.net, option strict, enums and overriding ToString

I have the following code:
Public Enum Country
Canada = 1
USA = 2
End Enum
When I want to see if the user has selected a value, I do:
ddl.SelectedValue = Country.Canada
Which works fine. However, if I turn on a warning for implicit conversion, this gives a warning. Changing it to
ddl.SelectedValue = Country.Canada.ToString()
fails, since the ToString() method returns "Canada" not "1".
What's the best way to get rid of the warning?
You can explicitly cast the SelectedValue to an int, or the Country as a string.
If CInt(ddl.SelectedValue) = Country.Canada
or
If ddl.SelectedValue = CStr(Country.Canada)
If you take the first option, you might need to explicitly declare your enum as Integer
Public Enum Country As Integer
The warning occurs because SelectedValue is a string, and Country is an Integer, so an implicit conversion occurs - just like it says!!
If you want the value '1' rather than 'Canada', you can explicitly cast it as an integer first, and then call .ToString() on the result of that.
ddl.SelectedValue = DirectCast(Country.Canada, Integer).ToString()

Resources