Auto Suggested Text Box with concatenated string with LINQ to SQL - asp.net

I'm creating a text box with auto-suggested. So, it works well. It suggests only first name, but I want it to suggest the full name (first and last name which two different columns). Take a look at the following code behind that worked as expected :
<System.Web.Services.WebMethod()> _
Public Shared Function GetNames(ByVal prefixText As String, ByVal count As Integer) As String()
Dim db As New DemoDataContext()
Return db.Students.Where(Function(n) n.FirstName.StartsWith(prefixText)).OrderBy(Function(n) n.FirstName).Select(Function(n) n.FirstName).Take(count).ToArray
End Function
Here's the mark-up :
<asp:TextBox ID="TextBox1" runat="server" Width="191px"></asp:TextBox>
<cc1:AutoCompleteExtender ID="TextBox1_AutoCompleteExtender" runat="server"
Enabled="True" minimumprefixlength="1" ServiceMethod ="GetNames" TargetControlID="TextBox1">
</cc1:AutoCompleteExtender>
I wrote the following code to try to get the text box to suggest the full name but it didn't work :
Dim query = (From s In db.Students _
Where s.FirstName.StartsWith(prefixText) _
Order By s.FirstName _
Select New With {.Name = s.FirstName & " " & s.LastName}).Take(count).ToArray
Return query
When I build the project it says "Value of type '1-dimensional array of (line 50)' cannot be converted to '1-dimensional array of String' because ' (line 50)' is not derived from 'String'"
Anyboy has a suggestion, please comment. Thank you.

Don't create a new anonymous object with a name attribute that is a string, just return the string itself:
Dim query = (From s In db.Students _
Where s.firstname.StartsWith(prefixText) _
Order By s.firstname _
Select s.firstname & " " & s.lastname).Take(count).ToArray

Related

How to deal with SqlDataReader null values in VB.net

I have the follwoing code that performs a query and returns a result. However, I looked around and found some examples to take care of null values but I get an error: "Invalid attempt to read when no data is present." I also got the error: "Conversion from type 'DBNull' to type 'Decimal' is not valid."
Can someone help me out with this code to prevent null values from crashing my program?
Private Sub EFFICIENCY_STACKRANK_YTD(ByVal EMPLOYEE As String)
Dim queryString As String = "SELECT " & _
" (SELECT CAST(SUM(TARGET_SECONDS) AS DECIMAL)/ CAST(SUM(ROUTE_SECONDS) AS DECIMAL) FROM dbo.APE_BUSDRIVER_MAIN WITH(NOLOCK) WHERE APE_AREA_OBJID = " & lblAreaOBJID.Text & " AND EMPLOYEE_NAME = '" & EMPLOYEE & "' AND YEAR_TIME = '" & cbYear.Text & "' AND ACTIVE = 1) AS RESULT1" & _
" FROM dbo.APE_BUSDRIVER_MAIN "
Using connection As New SqlConnection(SQLConnectionStr)
Dim command As New SqlCommand(queryString, connection)
connection.Open()
Dim reader As SqlDataReader = command.ExecuteReader()
If reader.Read Then
RESULT1 = reader("RESULT1")
Else
RESULT1 = 0
End If
End Using
End Sub
You have opened the reader, but have not asked it to actually read anything.
After this line:
Dim reader As SqlDataReader = command.ExecuteReader()
add
If reader.Read() Then
and wrap the result reading into this if statement, i.e.
If reader.Read() Then
Dim index As Integer = reader.GetOrdinal("RESULT1")
If reader.IsDBNull(index) Then
RESULT1 = String.Empty
Else
RESULT1 = reader(index)
End If
End If
Note that this works because your SQL should only return a single record. In the event that you were reading multiple records, you would need to call the Read statement in a loop until there were no more records, i.e.
Do While reader.Read()
Loop
I wanted to provide another, more-advanced, answer as an option. Many classes can be extended in .NET like this.
If you are regularly performing "Is NULL" checks like this in your applications, you can choose to extend the DataReader class once to have additional functions available everywhere in your application. Here is an example that creates an extension called "ReadNullAsString()" onto the data reader class. This makes a function that always returns String.Empty when a DbNull is encountered.
Part 1, place this module code in a new class file in App_Code if application is a website, otherwise place where ever you prefer. There are two overloads, one for the field's ordinal position (aka index), and one for the field's ColumnName.
Public Module DataReaderExtensions
''' <summary>
''' Reads fieldName from Data Reader. If fieldName is DbNull, returns String.Empty.
''' </summary>
''' <returns>Safely returns a string. No need to check for DbNull.</returns>
<System.Runtime.CompilerServices.Extension()> _
Public Function ReadNullAsEmptyString(ByVal reader As IDataReader, ByVal fieldName As String) As String
If IsDBNull(reader(fieldName)) Then
Return String.Empty
Else
Return reader(fieldName)
End If
Return False
End Function
''' <summary>
''' Reads fieldOrdinal from Data Reader. If fieldOrdinal is DbNull, returns String.Empty.
''' </summary>
''' <returns>Safely returns a string. No need to check for DbNull.</returns>
<System.Runtime.CompilerServices.Extension()> _
Public Function ReadString(ByVal reader As IDataReader, ByVal fieldOrdinal As Integer) As String
If IsDBNull(reader(fieldOrdinal)) Then
Return ""
Else
Return reader(fieldOrdinal)
End If
Return False
End Function
End Module
Step 2, call the new extension like so:
' no need to check for DbNull now, this functionality is encapsulated in the extension module.
RESULT1 = reader.ReadNullAsEmptyString(index)
'or
RESULT1 = reader.ReadNullAsEmptyString("RESULT1")

System.ArgumentException: String value can not be converted to a date

I have a web form that uses an Ajax date calendar. This works fine. The problem that i have is that when i submit my form i get the following message.
'String value can not be converted to a date' .AgendaDate = New SmartDate(txtAgendaDate.Text)
Here is my web form that holds the calendar and the associated text box...
<td>
<asp:TextBox ID="txtAgendaDate" runat="server" ForeColor="Black" ></asp:TextBox>
</td>
<td>
<asp:ImageButton runat="Server" ID="ImageButton1" ImageUrl="~/images/calendarpic.png"
AlternateText="Click here to display calendar" />
<cc1:calendarextender ID="CalendarExtender1" runat="server"
TargetControlID="txtAgendaDate" PopupButtonID="ImageButton1" >
</cc1:calendarextender>
</td>
I have a class with the associated properties on it for the web form. The rest of the fields work and submit data to the database except the textfield for the ajax calendar.
Here is my stripped down version for the code for the class and the txtAgendaDate code...
#Region " Agenda Variables "
'Declare Variables and data types and set default values
Private mAgendaID As Integer = 0
Private mOrganiser As String = ""
Private mMeeting As String = ""
Private mAgendaDate As SmartDate = New SmartDate()
#End Region
#Region " Constructors "
Public Sub New()
End Sub
Public Sub New(ByVal reader As SafeDataReader)
' Public Sub New(ByVal reader As SQLDataReader)
'Combine variables & property types
With reader
mAgendaID = .GetInt32("AgendaID")
mOrganiser = .GetString("Organiser")
mMeeting = .GetString("Meeting")
mAgendaDate = .GetSmartDate("AgendaDate")
End With
End Sub
#End Region
#Region "Properties"
'Define form field properies so that they can be used when adding the data to the database on the add button is pressed.
Public Property AgendaID() As Integer
Get
Return mAgendaID
End Get
Set(ByVal Value As Integer)
mAgendaID = Value
End Set
End Property
Public Property Organiser() As String
Get
Return mOrganiser
End Get
Set(ByVal value As String)
mOrganiser = value
End Set
End Property
Public Property Meeting() As String
Get
Return mMeeting
End Get
Set(ByVal value As String)
mMeeting = value
End Set
End Property
Public Property AgendaDate() As SmartDate
Get
Return mAgendaDate
End Get
Set(ByVal Value As SmartDate)
mAgendaDate = Value
End Set
End Property
#End Region
End Class
Here is my command that looks connects to the DB and at the stored procedure and also has the parameters.
Public Class Agenda_TempDAL
Public Shared Function AddAgenda_Temp(ByVal Agenda_Temp As Agenda_Temp) As Integer
'Declare i as integer as 0
Dim iAgendaID As Integer = 0
'Database conn, this is linked to the web config file .AppSettings
Using dbconnection As New SqlConnection(ConfigurationManager.AppSettings("dbconnection"))
dbconnection.Open()
'Command to state the stored procedure and the name of the stored procedure
Using dbcommand As SqlCommand = dbconnection.CreateCommand
With dbcommand
.CommandType = CommandType.StoredProcedure
.CommandText = "Stored_Proc_Name"
'Create parameter for AgendaID and output
Dim oParam As New SqlParameter
oParam.ParameterName = "#AgendaID"
oParam.Direction = ParameterDirection.Output
oParam.SqlDbType = SqlDbType.Int
'Create parameters for the remaining fields
.Parameters.Add(oParam)
.Parameters.AddWithValue("#Organiser", Agenda_Temp.Organiser)
.Parameters.AddWithValue("#Meeting", Agenda_Temp.Meeting)
.Parameters.AddWithValue("#AgendaDate", Agenda_Temp.AgendaDate.DBValue)
'Simply execute the query
dbcommand.ExecuteNonQuery()
End With
End Using
End Using
'Need to return the agendaID as an integer.
Return iAgendaID
End Function
End Class
And here is the code behind the button ion the web page. This is the page that causes the error based on the property / field. The problem lies on this line...
.AgendaDate = New SmartDate(txtAgendaDate.Text)
The whole code for the button is here...
Protected Sub btnAddAgendaTemplate_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnAddAgendaTemplate.Click
'This works alongside the Class named Agenda_Temp which has the properties and DB connection assigned to it for each web form field.
Dim oAgenda_Temp As New Agenda_Temp
'Within the object Agenda_Temp Class use the properties defined.
'They are required to be defined in the Agenda_Temp/ app code so we can use them within here.
With oAgenda_Temp
.Organiser = txtOrganiser.Text
.Meeting = txtMeeting.Text
.AgendaDate = New SmartDate(txtAgendaDate.Text)
'Within the object Agenda_Temp class use the defined DAL which includes all the DC connect and stored procedures.
oAgenda_Temp.AgendaID = Agenda_TempDAL.AddAgenda_Temp(oAgenda_Temp)
End With
End Sub
End Class
I understand that its telling me that the string value cannot be converted to a date but i don't know hoe to resolve this as i am new to .net 2010?
Any help much appreciated.
Convert the string to a date before newing it:
From MSDN:
string date = "01/08/2008";
DateTime dt = Convert.ToDateTime(date);
Your's would become
DateTime dt = Convert.ToDateTime(txtAgendaDate.Text)
Then pass the date to your SmartDate constructor:
oAgenda_Temp.AgendaDate = new SmartDate(dt)
The final result:
With oAgenda_Temp
.Organiser = txtOrganiser.Text
.Meeting = txtMeeting.Text
.AgendaDate = New SmartDate(Convert.ToDateTime(txtAgendaDate.Text))
'Within the object Agenda_Temp class use the defined DAL which includes all the DC connect and stored procedures.
oAgenda_Temp.AgendaID = Agenda_TempDAL.AddAgenda_Temp(oAgenda_Temp)
End With
As others have pointed out, you need to convert the input value to a DateTime. I don't know what the SmartDate() function is doing, but the error message clearly indicates that the value cannot be converted to a date.
Secondly, I would add some validation to make sure that the input is valid before you submit the page. Use the RequiredFieldValidator and CompareValidator or RegularExpressionValidator:
<asp:TextBox ID="txtDate" runat="server" ... />
<asp:RequiredFieldValidator ID="reqDate" runat="server" ErrorMessage="Required" Display="Dynamic" ControlToValidate="txtDate"></asp:RequiredFieldValidator>
<asp:RegularExpressionValidator ID="regDate" runat="server" ControlToValidate="txtDate" ErrorMessage="Please enter a valid date in the format (mm/dd/yyyy)" ValidationExpression="^(0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[- /.](19|20)\d\d$"></asp:RegularExpressionValidator>

ASP CascadingDropDown Control Causes IE Script timeout

Before a page is loaded, I use a subroutine to link DropDownList controls together:
Private Sub CreateCascadingDropDown(ByVal category As String, ByRef parentDDL As DropDownList, ByRef targetDDL As DropDownList)
Dim CDDL As New CascadingDropDown
With CDDL
.Category = category
If Not parentDDL Is Nothing Then
parentDDL.Items.Clear()
.ParentControlID = parentDDL.ID
End If
targetDDL.Items.Clear()
.TargetControlID = targetDDL.ID
.PromptText = SharedWeb.GC_SELECTONE
.PromptValue = "-1"
.LoadingText = "Please wait..."
.ServicePath = "/ajax/InvestmentProcess.asmx"
.ServiceMethod = "GetTaxo"
End With
'Page.ClientScript.RegisterForEventValidation(CDDL.UniqueID)
targetDDL.Parent.Controls.Add(CDDL)
End Sub
When the web service method is called, it executes the following code. Based on the category, it gets the appropriate data from the adapter.
<WebMethod()> _
Public Function GetTaxo(ByVal knownCategoryValues As String, ByVal category As String) As CascadingDropDownNameValue()
Dim log As ILog = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType)
log.Debug("GetSegmentTaxonomy(" + category + ") -> {" + knownCategoryValues + "}")
Dim kv As StringDictionary = CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues)
Dim adapter As New SegmentTaxonomyTableAdapters.SEGMENT_ARCHITECTURE_TableAdapter
Dim rows As DataRowCollection
Select Case category
Case InvestmentEdit.ST_SEG_ARCH
rows = New SegmentTaxonomyTableAdapters.SEGMENT_ARCHITECTURE_TableAdapter().GetData().Rows
Case InvestmentEdit.ST_LOB
If kv.ContainsKey(InvestmentEdit.ST_SEG_ARCH) Then
log.Debug("found seg architecture - > " + kv(InvestmentEdit.ST_SEG_ARCH))
rows = New SegmentTaxonomyTableAdapters.LINE_OF_BUSINESSTableAdapter().GetData(kv(InvestmentEdit.ST_SEG_ARCH)).Rows
End If
End Select
If Not rows Is Nothing Then
Dim results As New List(Of CascadingDropDownNameValue)
For Each row As DataRow In rows
log.Debug("ROW >>>> " + row("lov_label").ToString() + " : " + row("lov_cd").ToString())
results.Add(New CascadingDropDownNameValue(row("lov_label"), row("lov_cd")))
Next
Return results.ToArray
End If
Return Nothing
End Function
There are about 5 drop downs I need to link together. The top-level drop down control (myDDL) loads fine if it is the only one linked like so:
CreateCascadingDropDown("MyCat",Nothing,myDDL)
But when I link a second drop down control, Internet Explorer gives a script timeout. If I keep allowing the script to run, it just keeps giving me the prompt. If elect to discontinue running the script, I get a Method Error 12031 or Error 500 (and yes, I have the ScriptService() declaration in my web service file). Any ideas on what's causing this?
It turns out I just needed to add the following control from the Ajax Control Toolkit:
<ajax:ToolkitScriptManager ID="tsm" runat="server" />
Instead of .TargetControlID = targetDDL.ID I needed to use:
.TargetControlID = targetDDL.UniqueId

ASP.Net AutoCompleteExtender VB WebMethod not firing - why?

Definitely at my wits end here. This should be simple. In a page to create new user accounts, we have a database with a little of allowable users. To streamline getting the Email address of the new user correct, we want to use an AutoComplete extended textbox.
Now I know that WebMethods are working because I have a cascading-drop-down tied to web methods in another page.
As I'm just starting on this page, the code is simple.
The page itself:
<cc1:ToolkitScriptManager ID="ScriptManager2" runat="server"/>
<p></p> Please enter new user's Email:
<asp:TextBox ID="txtUser" runat="server" />
<cc1:AutoCompleteExtender runat="server" ID="autUser" TargetControlID="txtUser"
ServiceMethod="ScanGALUsers" ServicePath="~/AutoScan.asmx"
MinimumPrefixLength="3" CompletionSetCount="150" /> <p></p>
The .asmx file is simple:
<%# WebService Language="VB" CodeBehind="~/App_Code/VB_Code/AutoScan.vb" Class="AutoScan" %>
The WebMethod:
<System.Web.Script.Services.ScriptService()> _
<WebService(Namespace:="http://tempuri.org/")> _
<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Public Class AutoScan
Inherits System.Web.Services.WebService
<WebMethod()> _
Public Shared Function ScanGALUsers(ByVal strPrefix As String, ByVal intMaxCount As Integer) As String()
Dim arlResults As New ArrayList
Dim intCount As Integer
Dim dt As DataTable
Dim colParameters As New SortedList
SysDA.LogDebug("ScanGALUsers called with parameters: " & strPrefix & " and count of " & intMaxCount.ToString)
... Deleted for brevity ...
If intCount > 0 Then
Dim arrResults(intCount - 1) As String
arrResults = arlResults.ToArray(GetType(System.String))
Return arrResults
Else
Return Nothing
End If
End Function
End Class
I'm not even getting to the LogDebug statement. I've used all the same boilerplate code (Inherits, the 'WebService' tags, etc) that worked in the other WebMethod with the appropriate changes to the Class name but this really has me stumped.
What am I missing that I'm not even making it to the method?
Did you ever resolve this issue? Have you tried removing Shared from your WebService declaration? This has worked for me before (and I don't know why!).

add client script to asp.net page dynamically

I want to add javascript to asp.net page dynamically.
can anybody point me towards working example?
i know it can be done by using Page.ClientScript.RegisterClientScriptBlock
but i have no idea to use it.
MSDN
This is the MSDN link
if (!this.Page.ClientScript.IsClientScriptBlockRegistered(typeof(Page), "Utils"))
{
string UtilsScript = ResourceHelper.GetEmbeddedAssemblyResource("Utils.js");
this.Page.ClientScript.RegisterClientScriptBlock(typeof(Page), "Utils", UtilsScript, true);
}
I added the above example to help,
Here we test if the script is already registered (using the type an dkey we register against) get the script as a string from an embedded resource, then register (the last parameter of true tells the code to render Script tags).
hope this helps
P
An example to move the value of a Drop Down List to text field. The ID parameters are the Object.ClientID properties for the drop down list and text box.
Private Sub RegisterClientDropDownToTextBox(ByVal functionName As String, ByVal dropDownId As String, ByVal textBoxId As String)
Dim javascriptFunction As String = "function " & functionName & "() {" & _
"document.getElementById('" & textBoxId & "').value = document.getElementById('" & dropDownId & "').value;" & _
"}"
Dim javascriptWireEvent As String = "document.getElementById('" & dropDownId & "').onclick = " & functionName & ";"
Me.ClientScript.RegisterClientScriptBlock(Me.GetType(), functionName & "_ScriptBlock", javascriptFunction, True)
Me.ClientScript.RegisterStartupScript(Me.GetType(), functionName & "_Startup", javascriptWireEvent, True)
End Sub

Resources