vb global variable to be accesses by different classes - asp.net

I am new to VB and am working on an asp.net VB web application.
I have a partial class called s_new.aspx.vb which is the vb page behind the page s_new.aspx.
In this page there are a series of select dropdowns, which when selected lead to different options becoming available eg different select boxes appearing and or with different options.
One particular select box accesses a method in a different class (webcontrols).
My problem is that I need the web controls class to change its behavior based on a certain selection made in the s_new.aspx.vb page.
If I was using C# I would create a global variable and use that as a decision maker, but I cant seem to to this in VB.
below is a snippet of the code I am using:
Partial Class s_new
Protected Sub fldSourceofFunds_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles fldSourceofFunds.SelectedIndexChanged
Select Case fldSourceofFunds.SelectedIndex
Case 1
####
Case 2
###
Case 3
do something and set the variable
End Select
End Sub
Partial Class Webcontrols
Private Sub ReloadChildren()
If (variable from s_new has certain value) Then
ResetChildren()
Select Case PaymentMethodValue.ToLower.Trim
Case "payment via provider/platform"
Case "payment direct from client"
Case "payment via provider/platform and payment direct from client"
End Select
End if
End Sub
End Class
This is an existing project and I need to minimize the changes I make to the project, eg I am not able to make large changes to the structure to accommodate this change. As I said above, this would be a simple solution in C# and I assume it is simple here to.

Related

DropDownList Data Items Shared With All Web Users?

I'm designing a custom ASP.NET drop down list for a Web application to display a list of a lot of organizations.
Btw: I reviewed every other SO question related to dynamically creating a drop-down-list and I couldn't find an answer.
Since there's a lot of organizations I want to build the item list as fast as possible.
Here's my ideas:
I'd share the list like this:
Imports System.Web.UI.WebControls
Public Class Organizations
Inherits DropDownList
Private Shared m_Organizations As List(Of Organization) = Nothing
Public Sub CreateChildControls()
' If list not populated get list from database.
If m_Organizations Is Nothing Then
m_Organizations = Get_Organizations()
End If
For Each Org As Organization in Organizations
Item_Obj = New ListItem(Org.Name, Org.OrgId)
Items.Add(Item_Obj)
Next
MyBase.CreateChildControls()
End Sub
End Class
I did a test. I created a single web page with two copies the drop down list. I ran the web page.
On initial startup of the web page I see m_Organization Is Nothing and Get_Organizations is called.
When I select an organization I see m_Organizations IsNot Nothing so Get_Organizations is not called. That's what I wanted.
When I click on a Submit button on the test page I see m_Organizations IsNot Nothing so Get_Organizations is not called. That's what I wanted.
So Organizations is persisted across page postbacks.
Now my question.
Suppose 3 users are using the web application at the same time and they display the web page with the Organizations drop down list.
Will m_Organizations be shared with all three web applications so it is loaded only once for all three users?
Or, is each user in their own process and therefore GET_Organizations will be called a total of three times?
Thanks, Ed
Each user has their own web page, controls, and code values. They each get their own code copy and their code runs just FOR each user.
So, to load up the dropdown list? It not clear why you pulling into a list?
The base .net objects such as row, and dateable run a lot faster then lists. And these base types can be directly binded to the drop down list (no need for a loop).
So, your on load would be something like:
So, in page load event, you have this:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If IsPostBack = False Then
Me.Instutions.DataSource = Myrst("select ID,Institution from Institutions")
Me.Instutions.DataBind()
End If
End Sub
So, only on the page load do we fill up the combobox (drop down list). You check the "isPostback" value.
Now it possible that you using datasets (or the newer EF) for the data. But even in that case, you can get/grab the data table from that, and shove it directly into the dropdown list data source. You as a general rule will NOT run loops to fill these types of controls (gridview, listview, dropdownlist). They can be bound directly to the result of the data source without loops. And since each users will get their own copy of the data, and your code runs for each user? Then you do want to avoid things like loops - since that code will run separate for each user and each page post back.
So yes, each user gets their own web page, gets their own variables, and runs their own code 100% separate from each user. And that includes a copy of the datasets you have.
When the user selects a value from the drop down list? (yes, we have auto postback = true), and thus the code for that wlll look like:
Protected Sub Instutions_SelectedIndexChanged(sender As Object,
e As EventArgs) Handles Instutions.SelectedIndexChanged
' pk id from drop list = Instutions.SelectedValue
' text value from drop list = Instutions.DataTextField
End Sub
So, it only takes two lines of code to load up the dropdown list - even when you don't have a dataset, or are using EF.
Now, I did use a helper routine called myrst(), and it can be used to fill dropdown lists, datagrids, listviews etc. and once again only two lines of code, and no looping.
that "handy" routine is this:
Public Function Myrst(strSQL As String) As DataTable
Dim mycon As New SqlConnection(My.Settings.Test4)
Dim oReader As New SqlDataAdapter
Dim rstData As New DataTable
oReader.SelectCommand = New SqlCommand(strSQL, mycon)
Try
oReader.Fill(rstData)
Return rstData
Catch
Debug.Print(Err.Description)
Return Nothing
End Try
End Function
So when they select a value in the drop down list? You do get a full page post back, and your on-load event will run. And yes, EACH user has their own web page, and own copy of that code running - they are not relegated to each other in ANY way, and all local, global variables and code is run 100% in a separate session for each user. And each user also has their own Session() variables - and again they are 100% separate and not shared between all users.
So yes, all 3 users will each call and each load up their own copy of that data. (yes, it called 3 times). if that was not the case, then what would occur if you wanted to filter only companies or records belonging to the one user? so you can consider all code and even loading of data a 100% separate thing/concept and process for each user.

VB.Net: call sub from shared sub

I have some Ajax on a web page that feeds some data to a server-side VB.Net method. Once that data is in the server-side method, I need to call another server-side method to use the data I just collected. Here is a really simplified example:
' This method gets the input from the Ajax code on the web page.
<System.Web.Services.WebMethod> _
Public Shared Sub GetAwesome(VBInputText As String)
Dim strTest As String = VBInputText
' Now that we have collected input from the user,
' we need to run a method that does a ton of other stuff.
DisplayAwesome(VBInputText)
End Sub
Protected Sub DisplayAwesome(AwesomeIn As String)
' The real app does a lot more than this. For this example, it
' just sets the text of a literal.
litAwesomeResult.Text = AwesomeIn
End Sub
Of course, in the above example DisplayAwesome(VBInputText) gives me the 'Cannot refer to an instance member...' error. So, is it possible now to call Protected Sub DisplayAwesome from Public Shared Sub GetAwesome? I'm hoping to stay close to this sort of solution because it would play very well with the app as it is already written by another coworker.
unfortunately you cannot do this, Since the page method DisplayAwesome is defined as Protected and you requires an instance of the class to access the Protected method. But changes in another instance will not reflect in the current UI. another thing you can do is Make DisplayAwesome as Shared, but this time you cannot access the UI elements inside the shared function.
The thing you can do in this situation is, return data to the called method(in front end) and handle the litAwesomeResult.Text there
Call sub with name of Form Class like this:
FormName.DisplayAwesome(VBInputText)
In VB.Net, you can call the method not shared from a shared method with Name of Form Class by default instance, because The default instance is an object Form type that the VB application framework create and manage it, when the form is added to the project.
For more info see this :
VB.NET Default Form Instances

Why is my session variable being shared by multiple users in asp.net application

I have a session variable with a datatable assigned to it. For some reason the results from the datatable (display to user in a GridView) are being shared accross multiple users who are logged in. I thought each session was independent? So when one user makes changes then the other users see those results added to their results. Not sure why. I am not using Application variables.
I initialize the Session variable in Global_asax, then populate it on a button command after the user has filled out the required entries.
Imports System.Web.SessionState
Public Class Global_asax
Inherits System.Web.HttpApplication
Sub Session_Start(ByVal sender As Object, ByVal e As EventArgs)
Session("RDDT") = New DataTable
End Sub
End Class
As it stands, I did overlook something. There was a usercontrol that someone else had created that had Public variables. The application was treating them as static. All I did was remove them and changed where in use to Session varibles. The Application works as intended now.

Question about moving common routines to the App_Code Class

I have some common code that I would like to share between pages and I have been messing around with App_Code classes which is great but I would also like to use code that affects drop down lists example:
Sub Set_FirmType(ByVal Sender As Object, ByVal E As EventArgs)
subcategories.Visible = "false"
supplycategories.Visible = "false"
supplytypes.Visible = "false"
CityData.Visible="True"
CityDropDown.Visible="False"
CityDropDown.Items.Clear()
If DropFirmType.SelectedValue = "funeralhomes||FH" Then
CountryDropDown.ClearSelection()
CountryDropDown.Items.FindByValue("United States").Selected = True
CountryDropDown.Enabled = False
StateDropDown.Enabled = True
getStateDropDown("1")
End If
End Sub
Is their a way to put this in my App_Code class?
Thanks in advance!
It sounds like you have a sub-routine that is toggling visibility on multiple controls and setting some properties on a drop down list. You may want to consider packaging all of the controls into a single user control (.ascx) and putting the sub-routine in the code behind.
Housing the user control in the App_Code folder is not necessary for reuse across the application. Just drop the user control onto pages where you want the functionality.

update page text using web user control

I am building an application where a page will load user controls (x.ascx) dynamically based on query string.
I have a validation summary on the page and want to update it from the User Controls. This will allow me to have multiple controls using one Validation Summary. How can I pass data between controls and pages.
I know I can define the control at design time and use events to do that but these controls are loaded dynamically using Page.LoadControl.
Also, I want to avoid using sessions or querystring.
Found a way of doing this:
Step 1: Create a Base User Control and define Delegates and Events in this control.
Step 2: Create a Public function in the base user control to Raise Events defined in Step1.
'SourceCode for Step 1 and Step 2
Public Delegate Sub UpdatePageHeaderHandler(ByVal PageHeading As String)
Public Class CommonUserControl
Inherits System.Web.UI.UserControl
Public Event UpdatePageHeaderEvent As UpdatePageHeaderHandler
Public Sub UpdatePageHeader(ByVal PageHeadinga As String)
RaiseEvent UpdatePageHeaderEvent(PageHeadinga)
End Sub
End Class
Step 3: Inherit your Web User Control from the base user control that you created in Step1.
Step 4: From your Web User Control - Call the MyBase.FunctionName that you defined in Step2.
'SourceCode for Step 3 and Step 4
Partial Class DerievedUserControl
Inherits CommonUserControl
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
MyBase.PageHeader("Test Header")
End Sub
End Class
Step 5: In your page, Load the control dynamically using Page.LoadControl and Cast the control as the Base user control.
Step 6: Attach Event Handlers with this Control.
'SourceCode for Step 5 and Step 6
Private Sub LoadDynamicControl()
Try
'Try to load control
Dim c As CommonUserControl = CType(LoadControl("/Common/Controls/Test.ascx", CommonUserControl))
'Attach Event Handlers to the LoadedControl
AddHandler c.UpdatePageHeaderEvent, AddressOf PageHeaders
DynamicControlPlaceHolder.Controls.Add(c)
Catch ex As Exception
'Log Error
End Try
End Sub
Assuming you're talking about asp's validator controls, making them work with the validation summary should be easy: use the same Validation Group. Normally, I derive all usercontrols from a base class that adds a ValidationGroup property whose setter calls a overriden method that changes all internal validators to the same validation group.
The tricky part is making them behave when added dynamically. There are some gotchas you should be aware of, mainly concerning the page cycle and when you add them to your Page object. If you know all the possible user controls you'll use during design time, I'd try to add them statically using EnableViewState and Visible to minimize overhead, even if there are too many of them.

Resources