Routing in ASP.Net web app - asp.net

I am trying to use a single RouteURL to route to different pages dependent on the Route name but when I click on a button within my aspx page the page gets routed back to itself:
Here is what I have in my Global.asax
Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
' Code that runs on application startup
RegisterRoutes(RouteTable.Routes)
End Sub
Private Sub RegisterRoutes(ByVal routes As routecollection)
routes.MapPageRoute("1", "test", "~/default1.aspx")
routes.MapPageRoute("2", "test", "~/default2.aspx")
routes.MapPageRoute("3", "test", "~/default3.aspx")
End Sub
And here is what I have put in my default1.aspx page:
Protected Sub Button1_Click(sender As Object, e As System.EventArgs) Handles Button1.Click
Response.RedirectToRoute("2")
End Sub
Can anyone point me in the right direction please?

You have duplicated your routeUrl values in your mapped routes. What's happening is that it is routing to your second route, as found by name "2", but that route is http://yoursite/test, which, when it then processes the request, is matching to the first route entry, or default1.aspx.
You can't use the same routeUrl (i.e., "test"), for all of your mappings.
Further reading: ASP.NET Routing
An example of how you could change it:
Private Sub RegisterRoutes(ByVal routes As routecollection)
routes.MapPageRoute("2", "test/2", "~/default2.aspx")
routes.MapPageRoute("3", "test/3", "~/default3.aspx")
routes.MapPageRoute("1", "test/{*whatever}", "~/default1.aspx")
End Sub
Note in this example that route "1" is at the bottom. This is because routes are matched top-down, so more restrictive matches should be listed first. In this example yourdomain/test/2 will goto default2.aspx, yourdomain/test/3 will goto default3.aspx, and default1.aspx will essentially be the default, catching yourdomain/test, yourdomain/test/4, yourdomain/test/5, etc.

Related

Is there a need to restart server using URL Routing in ASP Net?

I'm using this article to implement Routing.
https://www.aspsnippets.com/Articles/Implement-URL-Routing-in-ASPNet-Web-Forms-40.aspx
The route registratin occours at the start of the application:
Private Sub Application_Start(sender As Object, e As EventArgs)
RegisterRoutes(RouteTable.Routes)
End Sub
Private Shared Sub RegisterRoutes(routes As RouteCollection)
routes.MapPageRoute("Customers", "Customers", "~/Customers.aspx")
End Sub
So do I need to restart the webserver every time I need to implement a new routing?

Friendly URLs and Query Strings

In my project (ASP.NET Web Forms) I want to use Friendly URLs, installed from NuGet.
I registered route in global.asax file:
Public Shared Sub RegisterRoutes(routes As RouteCollection)
routes.MapPageRoute("Route", "default/{id}", "~/default.aspx?id={id}")
End Sub
With this code, I can use default/123 instead of default?id=123. I want to add name, assigned to the id, in the url. So I can have url like this: default?123-Firstname-Lastnam. Name is saved in database, in single column. How can I add second parameter (name) to the url, add symbol - and display it without letters like this: řčš (because the application is in Chech language.
Thanks for answer.
To use FriendlyUrls, after you install it from NuGet, go to your global.asax and enable it:
Imports Microsoft.AspNet.FriendlyUrls
Public Class Global_asax
Inherits System.Web.HttpApplication
Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
RegisterRoutes(RouteTable.Routes)
End Sub
Sub RegisterRoutes(ByVal routes As RouteCollection)
routes.EnableFriendlyUrls()
End Sub
'rest of global
That is pretty much it. To get the values out of a URL for a page, you'll need to loop through the URL segments (don't forget Imports Microsoft.AspNet.FriendlyUrls):
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
For Each segment As String In HttpRequestExtensions.GetFriendlyUrlSegments(Request)
Dim val As String = segment
Next
End Sub
So visiting siteURL.com/default/123 will loop once and give you 123, while siteURL.com/default/122/Bilbo/Baggins will loop three times and give you 122, Bilbo, and Baggins.
Or, if you just want to use plain routing and not FriendlyUrls:
routes.MapPageRoute("id-route", "default/{id}", "~/default.aspx")
One good thing about routing is you can use the URL to pass variable data without using query strings. So the route to pass name data could look like
Sub RegisterRoutes(ByVal routes As RouteCollection)
routes.MapPageRoute("name-route", "default/{id}/{firstName}/{lastName}", "~/default.aspx")
End Sub
And then default.aspx could be hit with siteURL.com/default/123/Frodo/Baggins and has:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
Dim id As Integer = 0
Int32.TryParse(Page.RouteData.Values("id"), id)
Dim firstName As String = Convert.ToString(Page.RouteData.Values("firstName"))
Dim lastName As String = Convert.ToString(Page.RouteData.Values("lastName"))
'do something if id > 0
End Sub
Other Considerations: If you only want name in a single column, then you can combine the firstName and lastName variables for saving. Using - as a delimeter like you show in question isn't a good idea, as people can have hyphenated names. Saving name in a single column tends to cause problems as it makes it much harder to sort by first or last name, etc.
Also it appears you will be inserting into your database from a GET command. I would think this would be much more clear to do using PUT or POST.

ASP.NET DLL instances conflict

I am new to asp.net and i am trying to solve a problem.
I have created a simple aspx page (asp web site) that references a vb.net class.
I am handling one class instance using the session context object (don't know if there is a better way).
The class has a sub that sets a string value and a function that returns it.
I compile and run the web site project and then set the value "1" from one aspx page and the value "2" from another page (i open a second tab or browser by copying-paste the url from the first page) and then retrieve the values, both pages will show "2".
The same class in a vb.net form application (.exe) works just fine when the exe instances are running, the first returns the value "1" and the second the value "2". This is how i want it to work in my web site project, different pages different dll instances.
Class:
Public Class Class1
Private sExten As String
Public Sub setExten(value As String)
sExten = value
End Sub
Public Function getExten() As String
Return sExten
End Function
End Class
aspx:
Partial Class _Default
Inherits System.Web.UI.Page
'trying to ensure one instance is running
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
If Not Page.IsPostBack Then
Session.Add("ClassLibrary1", New ClassLibrary1.Class1)
End If
End Sub
'txtSetValue.text contains value "1" or "2"
Protected Sub btnSet_Click(sender As Object, e As EventArgs) Handles btnSet.Click
CType(Session.Item("ClassLibrary1"), ClassLibrary1.Class1).setExten(txtSetValue.text)
End Sub
'the txtShowValue shows "1" in the first and "2" in the second page
Protected Sub BtnGet_Click(sender As Object, e As EventArgs) Handles BtnGet.Click
txtShowValue.Text = CType(Session.Item("ClassLibrary1"), ClassLibrary1.Class1).getExten()
End Sub
End Class
Both pages are sharing the same Session.Item("ClassLibrary1"). You can try to store the value in a hidden field, or a invisible label.

Redirect in Master Page Before Content Page Load

I have code in my ASP.NET master Page_Init event page that checks if a user is authorized to be on the content page, and if not redirects them to the login page. This code works fine as far as the check itself.
However, I have discovered that the content Page_Load event still fires after the above redirect.
This is causing a problem on pages that assume the user is logged in and certain variables are set.
This is the master page code (simplified)
Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
...
If Access_Level > User_Level_ID Then
Response.Redirect("~/login.aspx", False)
End If
End Sub
The above test works fine, and the redirect line is executed, but doesn't take effect before the code below is fired and executes.
This is the content page code
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim Rec_IDs As New List(Of String)
Rec_IDs = Session("Rec_IDs")
lblCount.Text = String.Format("You have {0} records in your cart", CType(Rec_IDs.Count, String)) 'this gives an error if Session("Rec_IDs") is null
End Sub
I realize I can put code in each of my content pages to check if a user is logged in / authorized, but I wanted to control it all from one location if possible.
Am I doing something wrong? I've read so many pages that say the master page is the place to do the check.
Thanks. :-)
Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
...
If Access_Level > User_Level_ID Then
Response.Redirect("~/login.aspx", True)
End If
End Sub
Using Response.Redirect("~/login.aspx", True) will terminate the current page processing & redirect to desired page.
Though it is recommended to use "Response.Redirect("~/login.aspx", False)" but this will not terminate page execution. It will redirect after current page processing end.
It does so because the 2nd argument in your Response.Redirect is set to false - which means you're not ending the execution of the rest of the page.
If you set it to true, page execution ends (prevents the Page_Load of the content page/s from firing. EDIT: as well as any other subsequent Master page events for that matter)
Response.Redirect("~/login.aspx", True)
Check what it does to all your pages though....e.g. your login.aspx page shouldn't have the same master page the way the code is written above...

How can I call the Sub on the content page?

How can I call the Sub on the content page?
On the content page, there is let's say this:
Public Sub MySub()
End Sub
On the master page I have this:
Dim cph As ContentPlaceHolder = CType(Page.Form.FindControl("ContentPlaceHolder1"), ContentPlaceHolder)
Why do you need this? You can't be sure to have a particular contentpage. A Masterpage's purpose is re-usability and therefore many pages should use it. Why you need to access a special page?
What you could do is, add an event to the Masterpage, raise it when necessary and handle it in the ContentPage. For example...
in Master:
Partial Public Class ERPMaster
Inherits System.Web.UI.MasterPage
Public Event MasterLoaded(ByVal master As MasterPage)
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
RaiseEvent MasterLoaded(Me)
End Sub
In Content:
Private Sub Page_PreInit(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreInit
AddHandler DirectCast(Master, ERPMaster).MasterLoaded, AddressOf MasterLoaded
End Sub
Private Sub MasterLoaded(ByVal master As MasterPage)
MySub()
End Sub
Public Sub MySub()
End Sub
I assume that you are using ASP.NET?
Do you have a MasterType directive at the top of the content page file? If so, you can simply call functions on the master page using the following syntax:
Master.MySub()
The Master property of the content page is already typed to the page specified in the MasterType directive, so you can easily access any of the functions that it defines.
See MSDN for more information on interacting with master and client pages: http://msdn.microsoft.com/en-us/library/c8y19k6h(v=VS.100).aspx

Resources