request querystring in variable - asp.net

hello iam trying to get the id from a url and send it to the clint side this is what i did
this is my url :
http://localhost:53010/edit.aspx?Id=4
code behind
Public Partial Class Edit
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Handles Me.Load
End Sub
Private _myId As String = Request.QueryString("id")
Public Property myId() As String
Get
Return _myId
End Get
Set(ByVal value As String)
_myId = value
End Set
End Property
End Class
client
<%= myId%>
error
Request is not available in this context
this is also what i get when i move the private prop to page_load()
"private " is not valid on local variable declaration –
any idea what is going on
Thanks
i solve this problem here is the answer
Public Partial Class Edit
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Handles Me.Load
MyIdVal = Request.QueryString("id")
End Sub
Private _myIdVal As String
Public Property MyIdVal() As String
Get
Return _myIdVal
End Get
Set(ByVal value As String)
_myIdVal = value
End Set
End Property
End Class

That's a field initializer.
Field initializers run before the constructor and cannot access the instance they're initializing.
Therefore, you can't use the Request property there.
You need to move that to the constructor or Page_Load.

You're accessing the Request too early.
It will work if you set myId on Init, Page_Load or any other similar page event.

Try to set _myId in your PageLoad.

So I wanted a class with properties that were set from querystrings and found this thread. I also wanted to be able to access properties on the front page and even in JavaScript from a single location. Here is what I came up with:
// App_Code/QueryStrings.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
/// <summary>
/// Summary description for QueryStrings
/// </summary>
public class QS
{
private int id = -1;
public QS()
{
if (HttpContext.Current.Request.QueryString["id"] != null)
try
{
Int32.TryParse(HttpContext.Current.Request.QueryString["id"], out id);
}
catch
{
id = -2;
}
else
id = -3;
}
public int ID
{
get
{
return id;
}
}
}
Then you can call it from your .aspx page as follows:
<body>
<form id="form1" runat="server">
<div>
<% QS qs = new QS(); %>
ID = <%= qs.ID %>
</div>
</form>
</body>
Of course you can call from code behind with the same syntax.

Related

ASP.NET WebForms - VB.NET and SignalR

This is my Hub code (very simple):
Imports System
Imports System.Web
Imports Microsoft.AspNet.SignalR
Imports Microsoft.AspNet.SignalR.Hubs
Imports Microsoft.AspNet.SignalR.Client
Imports Microsoft.AspNet.SignalR.Messaging
Imports System.Threading.Tasks
Namespace SignalRChat
Public Class ChatHub
Inherits Hub
Public Sub Send(userName As String, message As String)
Clients.All.broadcastMessage(userName, message)
End Sub
End Class
End Namespace
This is my Aspx page code:
Imports System.Web.UI.WebControls
Imports Microsoft.AspNet.SignalR.Client
Imports System.Threading.Tasks
Public Class WebForm9
Inherits System.Web.UI.Page
Public Shared hubConnection As HubConnection
Public Shared chatHubProxy As IHubProxy
Public Sub MyChat_init(sender As Object, e As EventArgs) Handles Me.Init
If IsPostBack = False Then
hubConnection = New HubConnection("https://localhost:44343/")
hubConnection.TraceLevel = TraceLevels.All
hubConnection.TraceWriter = Console.Out
chatHubProxy = hubConnection.CreateHubProxy("ChatHub")
hubConnection.Start().Wait()
End If
chatHubProxy.On(Of String, String)("broadcastMessage", Sub(ByVal userName As String, ByVal message As String)
Dim li As ListItem = New ListItem
li.Value = userName & " - " & message
li.Text = userName & " - " & message
ListBox1.Items.Add(li)
End Sub)
End Sub
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
chatHubProxy.Invoke("Send", "Io", "Messaggio")
End Sub
End Class
I made a lot of tries but always ended up with no result... I added the postback checking because I noticed I was having the connection to the hub starting and starting again on each button_click...
By the way, if I add in the same project a page with JScript code I can catch all the messages sent on the JScript code, but none of the messages sent from the html page is catched by the aspx codebehind...
It's really strange because if I take away the listbox.items.add method and I put a "MsgBox" instead, then it fires up and work... but I have found no way to manage the "messages" from my codebehind and so update controls on my page... Maybe it's a connection mistake? Did anyone of you has any experience with SignalR and WebForms with VB.NET codebehind?
If this helps, I have a working client code (for testing purposes) in VB.NET WinForms app. (My Hub is in C#):
Hub (ASP.NET Core in net5.0 - created using Gerald Versluis' tutorial: https://www.youtube.com/watch?v=pDr0Hx67guk):
using Microsoft.AspNetCore.SignalR;
using System;
using System.Threading.Tasks;
namespace SignalR.Hubs;
public class OneHub : Hub
{
public async Task SendMessage(Message message)
{
Console.WriteLine($"{message.SentDateTime} Sender : {message.SenderId} - {message.MessageText}");
await Clients.All.SendAsync("MessageReceived", message);
}
}
WinForms (net4.8):
Imports Microsoft.AspNetCore.SignalR.Client
Imports SignalRWinForms.Client.Messaging.Models
Public Class Form1
Private connection As HubConnection
Sub New()
InitializeComponent()
connection = New HubConnectionBuilder().WithUrl("http://192.168.1.230:5296/chat").Build()
connection.On(Of Messages)("MessageReceived", Sub(Messages)
Invoke(Sub()
ReceiveMessage(Messages)
End Sub)
End Sub)
connection.StartAsync()
End Sub
Private Sub ReceiveMessage(msg As Messages)
chatMessages.Text &= $"{Environment.NewLine}{msg.MessageText}"
End Sub
Private Async Sub btnSendMessage_Click(sender As Object, e As EventArgs) Handles btnSendMessage.Click
Dim message = New Messages With {
.MessageText = txtMessage.Text,
.SenderId = 1111,
.ReceiverId = 2222,
.Token = "token",
.SentDateTime = DateTime.Now
}
Await connection.InvokeCoreAsync("SendMessage", args:={message})
txtMessage.Text = String.Empty
End Sub
End Class
Form1 is very simple - chatMessages label to populate messages, txtMessage textbox to write message and a btnSendMessage button.
Messages Class (common for both projects)
Public Class Messages
Public Property SenderId As Integer
Public Property ReceiverId As Integer
Public Property MessageText As String
Public Property Token As String
Public Property SentDateTime As DateTime
End Class

how to use webmethod on webform in asp.net

I have a user control on my web form which is as follows
I select the program year, category type , category and position group and then click search, it should return a collection which contains the programyearID, categorytypeID and positionGroupID for the corresponding selected items in the dropdownlist and pass it on to a webmethod which is already defined to get a specific certificationID.
Interface
Namespace SI.Certification.UserControl
Public Interface IUserSearchResultList
Property DataSource() As User.Learning.Business.HR.UserCollection
ReadOnly Property List() As User.Web.UI.WebControls.PagedRepeater
End Interface
End Namespace
here is this the code for my usercontrol1.vb
Public Class curriculum_search
Inherits System.Web.UI.UserControl
Implements IUserSearchResultList
Private _dataSource As UserCollection
Public Property DataSource As UserCollection Implements UserControl.IUserSearchResultList.DataSource
Get
Return _dataSource
End Get
Set(value As UserCollection)
End Set
End Property
Public ReadOnly Property List As PagedRepeater Implements UserControl.IUserSearchResultList.List
Get
Return ctlListControl
End Get
End Property
#Region "Public Properties"
Public Property ProgramYearID() As Int32
Get
If Me.ShowProgramYearSearch Then
If Me.lstProgramYear.SelectedValue = 0 Then
Return Integer.MinValue
Else
Return Me.lstProgramYear.SelectedValue
End If
Else
If ViewState("ProgramYearID") Is Nothing Then
Return Integer.MinValue
Else
Return ViewState("ProgramYearID")
End If
End If
End Get
Set(ByVal Value As Int32)
If Me.ShowProgramYearSearch Then
Me.lstProgramYear.SelectedValue = Value.ToString()
End If
ViewState("ProgramYearID") = Value
End Set
End Property
Public ReadOnly Property CategoryTypeID() As Int32
Get
If Me.lstCategoryType.SelectedValue = 0 Then
Return Integer.MinValue
Else
Return Me.lstCategoryType.SelectedValue
End If
End Get
End Property
Public ReadOnly Property CategoryID() As Int32
Get
If Me.lstCategory.SelectedValue = 0 Then
Return Integer.MinValue
Else
Return Me.lstCategory.SelectedValue
End If
End Get
End Property
Public Property PositionGroupID() As Int32
Get
If Me.ShowPositionCodeSearch Then
If Me.lstPositionGroup.Selected = -1 Then
Return Integer.MinValue
Else
Return Me.lstPositionGroup.Selected
End If
Else
If ViewState("PositionGroupID") Is Nothing Then
Return Integer.MinValue
Else
Return ViewState("PositionGroupID")
End If
End If
End Get
Set(ByVal Value As Int32)
If Me.ShowPositionCodeSearch Then
Me.lstPositionGroup.Selected = Value.ToString()
End If
ViewState("PositionGroupID") = Value
End Set
End Property
Public Property ShowPositionCodeSearch() As Boolean
Get
If ViewState("ShowPositionCodeSearch") Is Nothing Then
Return True
Else
Return ViewState("ShowPositionCodeSearch")
End If
End Get
Set(ByVal Value As Boolean)
ViewState("ShowPositionCodeSearch") = Value
If Not Value Then
spnPositionGroup.Visible = False
Else
spnPositionGroup.Visible = True
End If
End Set
End Property
Public Property ShowProgramYearSearch() As Boolean
Get
If ViewState("ShowProgramYearSearch") Is Nothing Then
Return True
Else
Return ViewState("ShowProgramYearSearch")
End If
End Get
Set(ByVal Value As Boolean)
ViewState("ShowProgramYearSearch") = Value
If Not Value Then
spnProgramYear.Visible = False
End If
End Set
End Property
#End Region
#Region "Events"
Public Event Submit(ByVal sender As Object, ByVal e As System.EventArgs)
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load, Me.Load
If Page.IsPostBack = False Then
If spnCategoryType.Visible = True Then
BindCertificationCategoryTypeCollection()
'method to bind the category collection
End If
If spnProgramYear.Visible = True AndAlso Me.ShowProgramYearSearch Then
BindProgramYearCollection(GetProgramYearCollection())
'method to bind the porgram year collection
End If
If spnPositionGroup.Visible = True AndAlso Me.ShowPositionCodeSearch Then
End If
lstPositionGroup.DefaultToPrimary = False
End If
End Sub
Public Sub btnSubmit_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles pnlSearch.SearchClick
RaiseEvent Submit(sender, e)
End Sub
This is the webmethod I have to use in my usercontrol to pass the parameters
<WebMethod(Description:="Get list of certification levels")> _
Public Function GetCertificationLevelsList(ByVal programYearId As Integer, ByVal PositionGroupId As String, ByVal CategoryId As
String) As User.Department.Application.Curriculum.Items
Dim items As User.Department.Application.Curriculum.Items = User.Department.Application.Curriculum.CategoryCollection.GetCategoryLevelsList(programYearId,
PositionGroupId, CategoryId)
items.Sort()
Return items
End Function
I am stuck here.
You can't use webmethods on Usercontrols. Webmethods must live on webpages. Since UserControls can live on multiple pages, you can't put a webmethod in a codebehind page of a UserControl.
So your options are:
Create an .asmx for your webmethod and call it from your webcontrol (old-skool)
Create a WCF enpoint (.svc) and call it from your webcontrol (semi-old-skool)
Create a WebAPI Controller and call it from your webcontrol (new-skool)
However, what you want to do is to call the webservice from the code-behind of your usercontrol. If you want to do this, you're mixing server-side and client-side. Your asmx is there to be used from the client-side. You will either need to copy the code from the asmx, or provide an abstraction that can be used in both the webservice and the usercontrol.

How to read a page variable from a master page

If a unique variable is assigned to each individual page; in this case PageID.
How can PageID be referenced from a master page on load?
PAGE VB
Partial Class Index
Inherits System.Web.UI.Page
Dim PageID As Integer = 1
End Class
MASTER VB
Partial Class MasterPage
Inherits System.Web.UI.MasterPage
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If PageID = 1 Then
...
End If
End Sub
End Class
I am aware this can be achieved with querystring however I am looking for a more efficient and secure solution due to the potential quantity of pages.
Expose a public property that returns that field, then you just have to cast the Page property in the MasterPage to the concrete type:
Dim index As Index = TryCast(Me.Page, Index)
If index IsNot Nothing Then
Dim pageID As Int32 = index.PageID
End If
And in the Index class:
Partial Class Index
Inherits System.Web.UI.Page
Private _PageID As Integer = 1
Public Property PageID As Int32
Get
Return _PageID
End Get
Set(value As Int32)
_PageID = value
End Set
End Property
End Class
Since you want that in every page you need to define an interface. You could let them implement the same Interface for example IPageable:
Public Interface IPagable
Property PageID As Int32
End Interface
Now let all pages implement it:
Partial Class Index
Inherits System.Web.UI.Page
Implements IPagable
Private _PageID As Integer = 1
Public Property PageID As Int32 Implements IPagable.PageID
Get
Return _PageID
End Get
Set(value As Int32)
_PageID = value
End Set
End Property
End Class
and change the MasterPage accordingly:
Dim pageable As IPagable = TryCast(Me.Page, IPagable)
If pageable IsNot Nothing Then
Dim pageID As Int32 = pageable.PageID
End If

How can I data bind <%# Eval("Object.Property")%> programmatically in VB.NET

I can bind a inner object property to gridview using the following setup at design time in an ASP.NET gridview
<asp:TemplateField HeaderText="ObjectName" >
<ItemTemplate>
<%# Eval("Object.property")%>
</ItemTemplate>
</asp:TemplateField>
but what I would like to do know is create this programmatically at runtime
i.e. define my columns, add them to the gridview and then databind
I'm not sure if this is what you want to achieve. But if you want to create columns dynamically according to your object's properties on runtime, have a look at following code(example is with BoundColumns, have a look at Volpa's answer when you need TemplateColumns):
ASPX:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false"></asp:GridView>
Codebehind:
Public Partial Class GridViewTest
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
BindData()
End If
End Sub
Private Sub BindData()
Dim cList As New List(Of CustomClass)
For i As Int32 = 1 To 10
Dim c As New CustomClass
c.ID = i
c.Name = "Object " & i
cList.Add(c)
Next
Dim model As New CustomClass
For Each prop As Reflection.PropertyInfo In model.GetType.GetProperties
If prop.CanRead Then
Dim field As New BoundField()
field.HeaderText = prop.Name
field.DataField = prop.Name
Me.GridView1.Columns.Add(field)
End If
Next
Me.GridView1.DataSource = cList
Me.GridView1.DataBind()
End Sub
End Class
Public Class CustomClass
Private _id As Int32
Private _name As String
Public Property ID() As Int32
Get
Return _id
End Get
Set(ByVal value As Int32)
_id = value
End Set
End Property
Public Property Name() As String
Get
Return _name
End Get
Set(ByVal value As String)
_name = value
End Set
End Property
End Class
One way would be to create a class that implements ITemplate interface:
public class PropertyTemplate : ITemplate
{
private string _value = string.Empty;
public PropertyTemplate(string propValue)
{
this._value = propValue;
}
public void InstantiateIn(Control container)
{
container.Controls.Add(new LiteralControl(this._value));
}
}
Then in your code-behind assing the ItemTemplate as following:
myTemplateField.ItemTemplate = new PropertyTemplate(myBusinessObject.MyProperty);
Another way would be to use Page.LoadTemplate if your custom template resides in the separate .ascx file:
myTemplateField.ItemTemplate = Page.LoadTemplate("~/MyTemplate.ascx");
And the .ascx file will look like:
<%# Eval("MyProperty") %>

How Do I Get an Object to Listen For its Property's Event?

I have an object of type SomeObject, with an event StatusChanged.
I have a property in SomeObject of type Status also with an event StatusChanged.
Within a private function in SomeObject, I would like to run some logic (including firing the StatusChanged event) in the event that Status has fired its StatusChanged event. I have been away from events for a while so it's a bit cloudy to me. How do I do this?
I'm writing in ASP.NET/VB.NET
Thanks :)
EDIT Ok, in the event that I can't do the above, how would I get the outer object (SomeObject) to fire its StatusChanged event when the inner object (Status) fires its StatusChanged event?
Events don't work that way. You can't perform logic based on whether an event has been fired. You can only write logic that takes place when an event is fired.
Ok, here's an attempt. It's been a while since I've done this in VB.NET, though:
Public Enum CurrentStatus
Good
Bad
End Enum
Public Class StatusEventArgs
Inherits EventArgs
Private _currentStatus As CurrentStatus
Public Property CurrentStatus() As CurrentStatus
Get
Return _currentStatus
End Get
Set(ByVal value As CurrentStatus)
_currentStatus = value
End Set
End Property
End Class
Public Class StatusClass
Public Event StatusChanged As EventHandler(Of StatusEventArgs)
Protected Overridable Sub OnStatusChanged(ByVal newStatus As CurrentStatus)
Dim s As New StatusEventArgs()
s.CurrentStatus = newStatus
RaiseEvent StatusChanged(Me, s)
End Sub
End Class
Public Class SomeClass
Private _status As StatusClass
Public Event StatusChanged As EventHandler(Of StatusEventArgs)
Protected Overridable Sub OnStatusChanged(ByVal newStatus As CurrentStatus)
Dim s As New StatusEventArgs()
s.CurrentStatus = newStatus
RaiseEvent StatusChanged(Me, s)
End Sub
Public Property Status() As StatusClass
Get
Return _status
End Get
Set(ByVal value As StatusClass)
If Not _status Is Nothing Then
RemoveHandler _status.StatusChanged, AddressOf StatusHandler
End If
_status = value
If Not _status Is Nothing Then
AddHandler _status.StatusChanged, AddressOf StatusHandler
End If
End Set
End Property
Private Sub StatusHandler(ByVal sender As Object, ByVal e As StatusEventArgs)
OnStatusChanged(e.CurrentStatus)
End Sub
End Class

Resources