FindControl method cannot locate the control on the page - asp.net

Ive tried searching for hours now and cannot find out why my code (aka, me.) is failing
Basically... I have a listview control which I'm passing a datatable of products (ID, Name, Description and Price columns), and im trying to make it so that when the "checkout" button is pressed, it parses through all the controls on the page, finds all the controls with the correct ID's and adds the items values to the cart.
ive checked all my ID's in the source code and they match up to the ones being requested by the FindControl method.
the error getting thrown back is:
Object reference not set to an instance of an object.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Line 21: For I = 1 To counter
Line 22: Dim cartItem As New Core.Types.CartItem
Line 23: cartItem.Name = CType(productsContainer.FindControl("product" + I.ToString()), HtmlGenericControl).InnerText
Line 24: cartItem.Quantity = Convert.ToInt32(CType(productsContainer.FindControl("quantity" + I.ToString()), HtmlSelect).Value)
Line 25: cartItem.Price = Convert.ToDecimal(CType(productsContainer.FindControl("price" + I.ToString()), HtmlGenericControl).InnerText.Remove(0, 1))
my .aspx code:
<div class="productsContainer" id="productsContainer" runat="server">
<asp:ListView runat="server" ID="lsvProducts">
<LayoutTemplate>
<ul class="lsvProducts">
<li class="highlight">
<div class="productName">
Product
</div>
<div class="productQuantity">
Number of Licenses
</div>
<div class="productPrice">
Price
</div>
</li>
<asp:PlaceHolder ID="itemPlaceHolder" runat="server"></asp:PlaceHolder>
</ul>
</LayoutTemplate>
<ItemTemplate>
<li>
<div style="display: none;">
<%=setCurrent()%>
</div>
<input type="hidden" id='productID<%#Eval("ID")%>' />
<div class="productName" id='product<%=currentItem%>'>
<%#Eval("Name")%>
</div>
<div class="productQuantity">
<select id='quantity<%=currentItem%>'>
<option selected="selected"
value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
<option value="10">10</option>
</select>
</div>
<div class="productPrice" id='price<%=currentItem%>'>
<%#"$" + Convert.ToDouble(Eval("Price")).ToString()%>
</div>
</li>
</ItemTemplate>
</asp:ListView>
</div>
<div class="clearer">
</div>
<div class="purchaseButton">
<asp:Button ID="btnAddCart" runat="server" Text="Add to Cart" />
</div>
</div>
and my code behind:
Dim counter As Int32
Public currentItem As Int32
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
'get all active products to display in the listing
Dim query As String = "SELECT * FROM Products WHERE Active = 1"
Dim dt As DataTable = DAL.Data.GetDataTable(query, "MainDB")
counter = dt.Rows.Count
lsvProducts.DataSource = dt
lsvProducts.DataBind()
End Sub
Protected Sub btnAddCart_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnAddCart.Click
'create a new instance of the cart
Dim cart As New Core.Types.Cart
'foreach item in the listing, find its details and add it to the shopping cart
For I = 1 To counter
Dim cartItem As New Core.Types.CartItem
cartItem.Name = CType(productsContainer.FindControl("product" + I.ToString()), HtmlGenericControl).InnerText
cartItem.Quantity = Convert.ToInt32(CType(productsContainer.FindControl("quantity" + I.ToString()), HtmlSelect).Value)
cartItem.Price = Convert.ToDecimal(CType(productsContainer.FindControl("price" + I.ToString()), HtmlGenericControl).InnerText.Remove(0, 1))
cartItem.ID = Convert.ToInt32(CType(productsContainer.FindControl("productID" + I.ToString()), HtmlGenericControl).InnerText)
cart.AddItem(cartItem)
Next
If (cart.isEmpty) Then
'empty cart, go nowhere. show a message saying the carts empty and to choose something.
Else
Response.Redirect("~/Checkout.aspx")
End If
End Sub
Public Function setCurrent()
currentItem = currentItem + 1
Return currentItem
End Function
Please help... this is driving me insane!
Thanks in advance :)

If you're in a datagrid/ repeater/ listview, to use the "FindControl" method, you'll have to iterate through the data items in the list view, then for each item peform the find control method. e.g. in C#:
foreach(RepeaterItem item in Repeater1.Items)
{
Literal lit = (Literal)item.FindControl("controlId");
}
I'm not sure thats the exact syntax but you get what I mean. You can't just use the find control method on the listview Id - the Ids of server controls in each item get re-written because you're looping through a collection...
Cheers, Sean

FindControl only looks in the current naming container. If you wish to find controls from a different naming container, you should have your own (recursive) implementation. For example:
private Control FindControlRecursive(Control parent, string id)
{
Control controlFound = parent.FindControl(id);
int i = 0;
while (controlFound == null && i < parent.Controls.Count)
{
controlFound = FindControlRecursive(parent.Controls[i++], id);
}
return controlFound;
}
After that use FindControlRecursive(productsContainer, "product" + I.ToString())

It looks like your nested controls are just basic Html controls? I'm not sure they'll be registered with ASP.NET unless you have runat="server" to register them as server-side controls.
It's been a while since I've done heavy ASP.NET dev, but in my prior experience we always used server-side controls and had no problems.

The other thing I noticed was that if your ContentPlaceHolder for a child page is nested inside a LoggedInTemplate inside a LoginView on a masterpage, then you can forget about using FindControl to grab the handle on a control inside the child page.

Related

Cannot pass value to page through HtmlGenericControl Property

Here is the .aspx file
<form id="form1" runat="server">
<input type="text" id="StringValue" runat="server"/>
<datalist id="dataList" runat="server"></datalist>
<% CreateContent(_sql)%>
</form>
And here is the .vb file (CreateContent)
Protected Sub CreateContent(ByVal sql As String)
Dim optList As New List(Of String)
optList = GetData(sql)
Dim table As New DataTable()
table.Columns.Add(New DataColumn("DataOptions"))
For Each opt In optList
table.Rows.Add(opt)
Next
For Each row In table.Rows
dataList.InnerHtml = dataList.InnerHtml & vbCrLf & String.Format("<option value='{0}'>", row(0))
Next
MsgBox(dataList.InnerHtml)
End Sub
When I tested the page, the MsgBox could actually show all the <option> elements. However, these contents can only exist in server side. <datalist> is always empty in page source. Anyone can explain what prevent the content being passed to the page and how to solve it?

asp.net and vb.net code for sending emails to multiple email address via smtp

I am a new in coding asp.net and vb.net. I have a web form built with asp.net and vb.net .
In the front end of the there are four fields constructed as below.
Recipient Mailing List : Drop down List (the options in the drop down list are such as Managers, HR, Admin, IT etc. Each option name contains multiple email addresses. i.e selecting one option means The user selects one group of of email address in the recipient field )
From Field : Text box (Read Only )
Subject : Text box
Message : Textarea
Send email button
The asp.net front end code is like below.
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="Server">
<div class="aux-body">
<div class="aux-body-content">
<div class="form-element">
<label>Recipient Mailing list </label>
<select runat="server" class="" id="comMailingList" datatextfield="name" datavaluefield="id"></select>
</div>
<div class="form-element">
<label> From </label>
<input style="width: 98%;" runat="server" id="txtFrom" type="text" value="Careers portal" readonly="readonly" />
</div>
<div class="form-element">
<label> Subject </label>
<input style="width: 98%;" runat="server" id="txtSubject" class="msubject" type="text" />
</div>
<div class="form-element">
<label> Message </label>
<textarea style="width: 98%; height: 100px;" runat="server" id="txtText" ></textarea>
</div>
<div id="button-group">
<asp:LinkButton runat="server" ID="btnSend" CssClass="btn" Text="Send Email"></asp:LinkButton>
</div>
</div>
</div>
</asp:Content>
In the back end i have structured the VB.net code like following. But i am unable to write the code that will send the email.
Partial Class E4_Candidate_broadcast
Inherits System.Web.UI.Page
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
If Not IsPostBack Then
If Not IsNothing(Request("b")) Then
cid.Value = Request("b")
End If
litMyEmail.Text = UserEmail
comMailingList.DataSource = Lists
comMailingList.DataBind()
End If
End Sub
Public ReadOnly Property Lists() As DataTable
Get
Return DB.GetData("select ml.id, ml.name + ' (' + cast( count(mlc.mailinglistid) as nvarchar(10)) + ' contacts)' name from mailinglist ml join mailinglistcontact mlc on ml.id = mlc.mailinglistid where ml.deleted = 0 and ml.createdby in (select userid from employeruser where employerid = #eid) group by ml.id, ml.name having count(mlc.mailinglistid) > 0 order by ml.name", DB.SIP("eid", LocalHelper.UserEmployerID()))
End Get
End Property
Protected Sub btnSend_Click(sender As Object, e As EventArgs) Handles btnSend.Click
If Not String.IsNullOrWhiteSpace(txtSubject.Value) Then
''Selects the recipients name and email address
Dim contacts = DB.GetData("select title, name, surname, email from mailinglistcontact where mailinglistid = #mlid", DB.SIP("mlid", comMailingList.Value)), _
mailers = New DataTable(), _
mailerqueue = New DataTable(), _
scheduleat = Now
For Each contact As DataRow In contacts.Rows
''''Code for sending email''''
Next
Response.Redirect("broadcast-sent-complete.aspx?i=" & cbId)
End If
End Sub
End Class
I have seen several examples by googling and found several links. But I am surely not understanding many things which are essential to code for sending emails.
I will be very much obliged if you help me write the code to send emails.
Thank you
Update
I have tried the following code. but its not working. i.e. the email is not sending.the code is going to the exception and saying message sending mailed. please have a look at my code and point me my error.
Dim message As New MailMessage()
For Each contact As DataRow In contacts.Rows
Try
Dim Client As New System.Net.Mail.SmtpClient
With Client
If WebConfigurationManager.AppSettings("smtpserver").Length > 0 Then
.DeliveryMethod = Net.Mail.SmtpDeliveryMethod.SpecifiedPickupDirectory 'Net.Mail.SmtpDeliveryMethod.Network
.PickupDirectoryLocation = "c:/outbox/"
.Host = WebConfigurationManager.AppSettings("smtpserver")
Else
.DeliveryMethod = Net.Mail.SmtpDeliveryMethod.PickupDirectoryFromIis
End If
With message
Dim FromAddress As MailAddress = New MailAddress("noreply#mypeoplebiz.com")
.From = FromAddress
.[To].Add(contact.Item("email").ToString())
.Subject = txtSubject.Value
.IsBodyHtml = True
.Priority = MailPriority.Normal
.BodyEncoding = Encoding.Default
If Not String.IsNullOrWhiteSpace(txtHtml.Value) Then
.Body = txtHtml.Value
End If
If Not String.IsNullOrWhiteSpace(txtText.Value) Then
.Body = txtText.Value
End If
End With
.Send(message)
End With
Catch Ex As Exception
_error = Ex.Message
End Try
Next

How can I convert this to asp.net? [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
In my classic asp app, I have a markup page with a bunch of checkboxes. The checkbox control ID is bscv.
Once a user checks a box and clicks submit, the value is processed on the next page called next.asp.
Based on the value of the checked box, I display the correct dropdown.
I use the following code on next.asp to display the correct dropdown.
If bsvc = "master" Then
' only master was checked
' "If the user checks only master checkbox, ...txtmaster with 2 options... is displayed."
%>
<select id="txtmaster" name="txtmaster">
<option value="">-Select a service-</option>
<option value="1">1</option>
<option value="2">2</option>
</select>
<%
Elseif InStr(bsvc, "master") > 0 Then
' Master was checked, but something else was also checked
' display txtmaster with all 7 options dropdowon 1 and 2
%>
<select id="txtmaster" name="txtmaster">
<option value="">-Select a service-</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
</select>
<%
Elseif Len(bsvc) > 0 Then
' something was checked, but not master
' " display only dropdown with 3 to 7 ."
%>
<select id="txtmaster" name="txtmaster">
<option value="">-Select a service-</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="4">5</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
</select>
<%
Else
Response.Write "Error: You did not check any business serviced"
End If
%>
This works great.
Now, on asp.net, I am using multiview and I am trying to accomplish the same.
On view1, I have the checkboxes. When I click next, I will like to display the correct dropdownlist based on the value of checked box.
How can I accomplish something similar as the code above?
Thanking you in advance.
One approach would be very similar to what you have...
Use an <asp:checkboxlist> in your markup.
Then for your submit button's on-click event, you can set your dropdown lists' 'visible' property to true or false, based on the checked values you find in your checkboxlist.
Alternatively, you could declare some listitem objects, have just one dropdownlist, and add/remove listitem based on the checked values from your checkboxlist.
For each myItem as listitem in myCheckboxlist
if ctype(myItem, checkox).checked then...
something along that line of thought anyway
I've never used Multiview, so forgive me if I'm totally off base. But it looks like the controls on view 1 should be available directly. Since you're using a Multiview you're never actually leaving the page, just posting back and changing the active view. So every control on view 1 (or any other view) is still accessible.
If you can't refer to the checkboxes directly, say if the checkboxes are dynamic (like databound or something), you should be able to use View1.FindControl or something similar.
Am I missing something?
'View1 contains three CheckBoxes and ButtonNext.
'View2 contains three DropDownLists and ButtonBack.
Protected Sub ButtonNext_Click(sender As Object, e As EventArgs) Handles ButtonNext.Click
SetListVisibility()
MultiView1.SetActiveView(View2)
End Sub
Protected Sub ButtonBack_Click(sender As Object, e As EventArgs) Handles ButtonBack.Click
MultiView1.SetActiveView(View1)
End Sub
Private Sub SetListVisibility()
If CheckBox1.Checked Then
If CheckBox2.Checked Or CheckBox3.Checked Then
DropDownList1.Visible = False
DropDownList2.Visible = False
DropDownList3.Visible = True
Else
DropDownList1.Visible = True
DropDownList2.Visible = False
DropDownList3.Visible = False
End If
Else
DropDownList1.Visible = False
DropDownList2.Visible = True
DropDownList3.Visible = False
End If
End Sub

ASP.NET MVC: on button click, call display multiple ActionResults in different windows

I have a form that has a drop-down list of values and a submit button.
Currently, when you click on the submit button, a stored procedure is called and then the application generates a url and then the ActionResult is a Redirect to a new window. The url is based on the currently selected value in the dropdown list.
Our client wants another button that when clicked, will basically do the same thing, but FOR ALL VALUES in the drop down list.
Basically, on click, multiple windows will be opened, whose urls each based on a value in the drop down list.
I just started working with MVC and research confused me even more. I'm hoping someone can point me in the right direction.
Should I handle this via some sort of loop in javascript? How? Can you give some examples, please?
ASPX Portion:
<div id="MyContainer" class="select-report">
<%
using (Html.BeginForm(MyManager.Query.Actions.GenerateReport(null), FormMethod.Post, new{target="_blank"}))
{%>
<select name="SearchText" class="my-values-select">
<% foreach (var cc in Model.MyCentresList)
{%>
<option value="<%=Html.Encode(cc.Name) %>">
<%=Html.Encode(cc.Name) %></option>
<% } %>
</select>
<input type="hidden" name="SearchType" value="MyCentre" />
<input type="submit" value="Generate" name="EntityName" />
<% } %>
</div>
Code-Behind:
public virtual ActionResult GenerateReport(GenerateReportOperation operation)
{
string entityName = operation.SearchText;
int entityType = (int)operation.SearchType;
string requestID1 = <code here that calls a stored procedure, a value is returned>;
string requestID2 = <code here that calls a stored procedure, a value is returned>;
string urlString = <code here that contructs the URL based on the values of entityName, entityType, requestID1, requestID2>;
return Redirect(urlString);
}
You would have to use JavaScript to open new windows for each individual HTTP request.

mvc3 html.Dropdownlist() and html.beginform()

Hi guys I have a dropdownlist and a submit button in my view.
I want the user to be able to select an item in the dropdownlist that calls an action method in the controller that gets data from the database.
I also have a button and I want the user to be able to select a checkbox in a grid and click the submit button to pass the value of the checkbox to an action method in the controller.
The problem is when I select an item from the dropdownlist it calls the action method for the submit button "DiscontinueProduct" and
not the action method for the dropdownlist ("GetProductByID"), can someone please tell me what I'm doing wrong?
Here is a my code.
Thanks in advance.
=============
view
<div>
#Using Html.BeginForm("GetProductByID", "Product")
#Html.DropDownList("CategoryID", DirectCast(ViewData("Categories"), SelectList), " -- Choose One -- ", New With {Key .onchange = "$('form').submit();"})
End Using
</div>
#Using Html.BeginForm("DiscontinueProduct", "Product")
#<text>
<table>
<tr>
<th></th>
<th>ProductName</th>
<th>SupplierID</th>
<th>CategoryID</th>
<th>Discontinued</th>
</tr>
#For Each item In Model
#<tr>
<td>
#Html.ActionLink("Edit", "Edit", New With {.id = item.ProductID}) |
#Html.ActionLink("Details", "Details", New With {.id = item.ProductID}) |
#Html.ActionLink("Delete", "Delete", New With {.id = item.ProductID})
</td>
<td>#item.ProductName</td>
<td>#item.SupplierID</td>
<td>#item.CategoryID
<input type="checkbox" name="task" id="isTaskSelected" value=" #item.CategoryID.ToString() " />
</td>
<td>#item.Discontinued</td>
</tr>
Next
</table>
<div id="btncomplete" style="display: none">
<input type="submit" value="Discontinue" />
</div>
</text>
End Using
=====================
Controller
Function GetProductByID(ByVal id As Integer) As ActionResult
Dim cquery2 = From product In db.Products
Where product.CategoryID = id
viewmodel.ProductList = cquery2.ToList()
Return PartialView("Products", viewmodel.ProductList)
Return PartialView("Products", viewmodel.ProductList)
End Function
<HttpPost()> _
Function DiscontinueProduct(ByVal collection As FormCollection) As ActionResult
Try
' Code to update product field as discontinue.
Return RedirectToAction("Index")
Catch
Return View()
End Try
End Function
It seems that you have to prevent the SUBMIT action for your drop-down list. Have a look here How to prevent buttons from submitting forms

Resources