Reading query-string in asp.net without specifying any page name - asp.net

How to read any strings in a aspx page.
example: http://foo.com/bike stand
I want to read/get the strings in a specified aspx page.
expected page string is bike stand
expected page is getstring.aspx
Here i like to read the string and redirect to specified page.
Note: I like to do this in just ASP.Net (Not with MVC)

You can probably solve this using a Route. I have made a simple demo, that you can try out in just a couple of minutes. In the Global.asax.cs file, add this method:
void RegisterRoutes(RouteCollection routes)
{
routes.MapPageRoute("Products",
"Products/{product}", "~/getstring.aspx",
false,
new RouteValueDictionary { { "product", "NoneSelected" } }
);
}
In the same file, in the already existing void Application_Start(object sender, EventArgs e) method, add RegisterRoutes(RouteTable.Routes);:
void Application_Start(object sender, EventArgs e)
{
RegisterRoutes(RouteTable.Routes);
}
With this, you have configured a Route which will take a request like this:
http://foo.com/Products/bike%20stand
and map it to getstring.aspx. Note that I have url encoded the space in the url.
In getstring.aspx you can access the value ("bike stand") like this:
protected void Page_Load(object sender, EventArgs e)
{
string routeValue = "";
if (RouteData.Values.ContainsKey("product"))
routeValue = RouteData.Values["product"].ToString();
//routeValue now contains "bike stand"
SelectedProduct.Text = routeValue;
}
I have set up the Route in this sample on the path "Products" beneath the application folder. I don't recommend that you setup your route directly under the application folder as in the question. You can do it though if you absolutely want to:
void RegisterRoutes(RouteCollection routes)
{
routes.MapPageRoute("Products",
"{product}", "~/getstring.aspx",
false,
new RouteValueDictionary { { "product", "NoneSelected" } }
);
}

It may not the best way to fulfill your need but if you want to get the string part from URL you may use URI Segments.
HttpContext.Current.Request.Url.Segments.Select(x=>x.TrimEnd‌​('/')).Skip(2).ToArr‌​ay();
OR
new Uri("http://www.someurl.com/foo/xyz/index.htm#extra_text").Segments
Results: [ "/", "foo/", "xyz/", "index.html" ]
After reading string you can do whatever you want like redirection etc

You could use the IIS URL Rewrite Module for this. When installed you can create a rule in the Web.Config System.Webserver node that rewrites the url so the string can be processed in code behind as a QueryString.
<rewrite>
<rules>
<rule name="getString" stopProcessing="true">
<match url="^([a-z0-9- /]+)$" ignoreCase="true"/>
<action type="Rewrite" url="getstring.aspx?string={R:1}"/>
</rule>
</rules>
</rewrite>
Then you can simply get the string value with this:
string getString = Request.QueryString["string"];
But his will create a problem if there are other pages than getstring.aspx than need to be accessed since every request is now being send to getstring.aspx. Maybe it's better to use a prefix so that you can identify the request URL as being one that has a string.
http://foo.com/getstring/bike stand
<match url="^getstring/([a-z0-9- /]+)$" ignoreCase="true"/>

Related

Routing in Web forms not working

This is the code in Global.asax
void Application_Start(object sender, EventArgs e)
{
System.Web.Routing.RouteTable.Routes.MapPageRoute("Page1","{Param1}/{Param2}","~/FirstPage.aspx");
System.Web.Routing.RouteTable.Routes.MapPageRoute("Page2","Xyz/{Param3}","~/Second.aspx");
}
Now i'm trying to redirect to some page e.g. xyz/test1,xyz/test2,xyz/test3. It's always getting redirected to FirstPage, not the second page which is what is expected and i'm trying to do.
How to implement this? Any suggestions.
Please make sure below important things are met before you start creating routing,
•Define custom URL patterns that are not dependent on physical file names.
•Generate URLs based on route URL parameter values by using markup or code.
•In a routed page, retrieve values passed in URL segments by using markup or code.
Try below code to implement routing,
1. In Application_start method you can only register the routes as below,
void Application_Start(object sender, EventArgs e)
{
RegisterRoutes(RouteTable.Routes);
}
Create below method after Session_End method in you global.asax file,
void RegisterRoutes(RouteCollection routes)
{
}
In the RegisterRoutes method, add the following code,
routes.MapPageRoute("SalesRoute",
"SalesReport/{locale}/{year}",
"~/sales.aspx");
This code adds a route that is named SalesRoute. You are naming this route because it has the same parameter list as the route that you will create in the following step. Assigning names to these two routes enables you to differentiate them when you generate URLs for them.
More details refer: https://msdn.microsoft.com/en-us/library/dd329551.aspx

Action filter attribute while opening image url

My requirement is like when someone opens url of any files from my asp.net mvc web site I want to track details of that user. Please note I have already added some query string, so only when opens url with that query string I want to track.
For another Action Methods I have already added query string to track via action filter. In action filter I am checking for that query string and if query string is not null and has some value then track that click.
But this logic will not work for direct URLs of files. For more details please see below example URLs.
http://wwww.example.com/Home/MyAction?trackerId=123 - TRACKING
http://wwww.example.com/Upload/Files/abc.jpg?trackerId=123 - NOT TRACKING
So any suggestions?
You could access all requests via the following in Global.asax file.
protected void Application_BeginRequest(Object sender, EventArgs e)
{
try {
var app = sender as HttpApplication;
var trackerId = app.Request.QueryString["trackerId"]
...do stuff...
}
catch { }
}

Rewriting dynamic URL ASP.net

I know how to rewrite url into web.conf but the problem is that I have to know from the id given in the url wich name to put into the rewrited url for example
foo/5 should be foo/bar because in the database the id 5 have the name "bar"
i also have the class method that tell me which name is assignd the witch id
So, I want to call the class from web.config to take the exact name for the corresponding id and then rewrite the URL
I saw the possibility of using custom configuration class but do not know how to use it.
Could you please tell me how or give me one other suggestion?
The general concept is that I take an incoming url (request) and map that to a specific page. Like /blog/my-awesome-post will be rewritten to Blog.aspx?id=5.
public class UrlRewriteModule : IHttpModule
{
public void Dispose()
{
// perform cleanup here if needed.
}
public void Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(context_BeginRequest); // attach event handler for BeginRequest event.
}
void context_BeginRequest(object sender, EventArgs e)
{
// get the current context.
HttpContext context = ((HttpApplication)sender).Context;
// the requested url
string requestedUrl = context.Request.Path; // e.g. /blog/my-awesome-post
// if you want to check for addtional parameters from querystring.
NameValueCollection queryString = context.Request.QueryString;
// perform db calls, lookups etc to determine how to rewrite the requested url.
// find out what page to map the url to.
// lets say that you have a page called Blog, and 'my-awesome-post' is the title of blog post with id 5.
string rewriteUrl = "Blog.aspx?id=5";
// rewrite to the path you like.
context.RewritePath(rewriteUrl);
}
}
You would need to add the module to the modulelist in web.config:
IIS pre version 7.:
<system.web>
<httpModules>
<add name="UrlRewriteModule" type="Assembly.Name.UrlRewriteModule, Your.Namespace.Here" />
....
</httpModules>
.....
</system.web>
IIS 7 and newer:
<system.webServer>
<modules>
<add name="UrlRewriteModule" type="Assembly.Name.UrlRewriteModule, Your.Namespace.Here" />
....
</modules>
....
</system.webServer>

ASP.Net WebForms Routing Single Route for Multiple Destinations

I am looking into setting database routing up for a new website I plan to create. I have been looking at the following tutorial with regards to utilising friendlyUrls from a database:
http://www.asp.net/web-forms/tutorials/aspnet-45/getting-started-with-aspnet-45-web-forms/url-routing
However, I would like to use the same route structure for multiple entities. Meaning:
mysite.com/{PlayerName} goes to player.aspx
mysite.com/{TeamName} goes to team.aspx
… and so on …
Could somebody point in the right direction of achieving this with asp.net. Is it possible using the built in routing engine, or should I be looking to code my own HTTPModule for this?
Thanks
David
I'm not sure why so many people say that this cannot be done with routing - maybe I'm not getting something, but the same logic that apparently makes the accepted answer a valid option should be perfectly applicable to a custom route handler, e.g. IRouteHandler or something derived from System.Web.Routing.RouteBase.
You can add "managers" to your RouteCollection (RouteTable.Routes) in the manner of:
routes.Add("MyRoutName", new MyCustomRouteBaseThing())
... Or:
routes.Add(new Route("whatever/{possiblySomething}", new RouteValueDictionary {
{"whatever", null}
}, new MyImplementationOfIRouteHandler()));
... Etcetera, depending on your needs.
If you go with the RouteBase alternative for example, override GetRouteData(), GetVirtualPath() and whatnot. I'm not saying it's necessarily a better option than the accepted answer, I just don't see why routing should be deemed not viable. (What am I missing?)
EDIT: At the time I wrote the above, the "accepted answer" was the one about URL rewriting posted by Tasos K, to whom the bounty was also rewarded. The accepted answer has since been reassigned.
Write two constraints which return boolean whether segment is a team or not / a player or not.
public class IsTeamConstraint : IRouteConstraint
{
public bool Match
(
HttpContextBase httpContext,
Route route,
string parameterName,
RouteValueDictionary values,
RouteDirection routeDirection
)
{
return SomeService.IsTeam(values["teamName"]);
}
}
public class IsPlayerConstraint : IRouteConstraint
{
public bool Match
(
HttpContextBase httpContext,
Route route,
string parameterName,
RouteValueDictionary values,
RouteDirection routeDirection
)
{
return SomeService.IsPlayer(values["playerName"]);
}
}
Set constraint in page route.
void RegisterCustomRoutes(RouteCollection routes)
{
routes.MapPageRoute(
"Team",
"{teamName}",
"~/Team.aspx",
false,
null,
new RouteValueDictionary { { "isTeam", new IsTeamConstraint() } }
);
routes.MapPageRoute(
"Player",
"{playerName}",
"~/Player.aspx",
false,
null,
new RouteValueDictionary { { "isPlayer", new IsPlayerConstraint() } }
);
}
Now when a page is requested registered page routes will use constraint to check that the route is valid and execute page if it is.
I haven't tried this in ASP.Net Forms but I've applications running with constraints developed in ASP.Net MVC. Both type of application (Forms and MVC) shared common routing logic.
I also don't know how this can be done using routing. But one way to achieve this is using URL rewriting instead. The whole process has a few steps and it is rather simple to make.
Applying the URL rewriting
You add at the Global.asax the following function.
void Application_BeginRequest(object sender, EventArgs e)
{
//Here you will get exception 'Index was outside the bounds of the array' when loading home page, handle accordingly
string currentsegment = Request.Url.Segments[1];
string RewritePath = "";
if (IsTeam(currentsegment))
{
RewritePath = "~/team.aspx?team=" + currentsegment;
}
if (IsPlayer(currentsegment))
{
RewritePath = "~/player.aspx?player=" + currentsegment;
}
if (RewritePath != "") {
// Adding all query string items to the new URL
for (int I = 0; I <= Request.QueryString.Count - 1; I++)
{
RewritePath = RewritePath + "&" + Request.QueryString.Keys[I] + "=" + Request.QueryString[I];
}
Context.RewritePath(RewritePath);
}
}
So if the URL has is /some-title-here you can get the some-title-here part using the Request.Url.Segments array.
Then based on that your code detects if this title is a team or a player. In any case you change internally the URL by calling the Context.RewritePath(...).
One important thing is that you need to add all the query string items manually in order to pass them to your pages.
Also, inside your code the Request.Url will know the rewritten URL, not the original.
A quick way to test it is to implement the IsTeam(...) and IsPlayer(...) function as below. With only this code when hitting /player-tasos the ~/player.aspx?player=player-tasos page loads and when hitting /team-stackoverflow the ~/team.aspx?team=team-stackoverflow page loads.
private bool IsTeam(string segment)
{
return segment.StartsWith("team");
}
private bool IsPlayer(string segment)
{
return segment.StartsWith("player");
}
So far this approach works but it has one main issue. When there is a PostBack the URL changes to the one you have set in the Context.RewritePath(...)
Avoiding PostBack issue
To avoid this issue you need to add to your projects two ASP.NET folders
App_Browsers
App_Code
In the App_Code folder you create a file FormRewriter.cs and add the following code (In my demo the root namespace is WebFormsRewriting)
using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Web;
using System.Web.UI;
namespace WebFormsRewriting
{
public class FormRewriterControlAdapter : System.Web.UI.Adapters.ControlAdapter
{
protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
base.Render(new RewriteFormHtmlTextWriter(writer));
}
}
public class RewriteFormHtmlTextWriter : System.Web.UI.HtmlTextWriter
{
public RewriteFormHtmlTextWriter(HtmlTextWriter writer)
: base(writer)
{
this.InnerWriter = writer.InnerWriter;
}
public RewriteFormHtmlTextWriter(System.IO.TextWriter writer)
: base(writer)
{
base.InnerWriter = writer;
}
public override void WriteAttribute(string name, string value, bool fEncode)
{
// If the attribute we are writing is the "action" attribute, and we are not on a sub-control,
// then replace the value to write with the raw URL of the request - which ensures that we'll
// preserve the PathInfo value on postback scenarios
if ((name == "action"))
{
HttpContext Context = default(HttpContext);
Context = HttpContext.Current;
if (Context.Items["ActionAlreadyWritten"] == null)
{
// Because we are using the UrlRewriting.net HttpModule, we will use the
// Request.RawUrl property within ASP.NET to retrieve the origional URL
// before it was re-written. You'll want to change the line of code below
// if you use a different URL rewriting implementation.
value = Context.Request.RawUrl;
// Indicate that we've already rewritten the <form>'s action attribute to prevent
// us from rewriting a sub-control under the <form> control
Context.Items["ActionAlreadyWritten"] = true;
}
}
base.WriteAttribute(name, value, fEncode);
}
}
}
In the App_Browsers folder you create a file Form.browser and add the following snippet. Note here to put the class name of the Adapter with its namespace.
<browsers>
<browser refID="Default">
<controlAdapters>
<adapter controlType="System.Web.UI.HtmlControls.HtmlForm"
adapterType="WebFormsRewriting.FormRewriterControlAdapter" />
</controlAdapters>
</browser>
</browsers>
And that's it. Adding those two files will handle the PostBack issue. If you put the FormRewriter.cs outside the App_Code folder it will not work. Also those two folders must be uploaded to the production server.
I have used this approach for years in .NET 3.5 and .NET 4.0 without any problems. Today I also tested it in a .NET 4.5 Web Forms project and it works with no issues.
All of the above are based on a ScottGu's article about the subject
As others have pointed out... it would be much better NOT to use this route for both Players and Teams.
It would be preferable to setup two routes...
mysite.com/player/{PlayerName}
mysite.com/team/{TeamName}
In this way you can drive all "player" traffic to Player.aspx, and "team" traffic to Team.aspx, nice and easy.
However... If you really have to support a single route, I recommend that you add it as a third option, and use a 301 Redirect to one of the two above routes.
mysite.com/{PlayerOrTeamName} -> Route.aspx
Let Route.aspx handle requests that don't map to physical files.
Then your Route.aspx code needs to function as a 404 Error handler, but with a catch.. It will check the Players data and the Teams data for an exact match. If it finds one it should do a 301 permanent redirect to the correct /player/ or /team/ route.
Using...
string strCorrectURL = RouteTable.Routes.GetVirtualPath(null, "player", new RouteValueDictionary { { "Name", strValue }});
Response.StatusCode = 301;
Response.Status = "301 Moved Permanently";
Response.AddHeader("Location", strCorrectURL);
Response.End();
This will give you the functionality of a single path, but tell search engines to index the more precise path.
You could skip the RouteTable altogether and just put this code into your default 404 handler.

Text URL for website in asp.net

I am developing my blog website in asp.net.
I am saving my blog post in sql server 2005 database.
I am storing like this in my database
PostId INT IDENTITY
PostText
PostAuthor
PostedDate
IsActive
So, at the code side when user is clicking on the tag/link. It is comming like this
http://www.mysite.com/readBlog.aspx?Id=2
On the readBlog.aspx page I am reading the URL and fetching the data from the database. But this is something unprofessional. I want URL like this
Scott Gu post
How can I achieve it in simpler manner?
EDIT
It is just when I want to share the URL of my website I can do like this
http://www.mysite.com/readBlog/How-to-install-visual-studio
Take a look onto ASP.NET Routing.
Just register a route in your Global.asax:
protected void Application_Start(object sender, EventArgs e)
{
RegisterRoutes(RouteTable.Routes);
}
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapPageRoute("readblog",
"readblog/{id}/{title}",
"~/readBlog.aspx");
}
and then it could be accessed by using e.g.:
var path = RouteTable.Routes.GetVirtualPath(
null,
"readblog",
new RouteValueDictionary {{ "id", blogId }, { "title", URLFriendly(title) }}
).VirtualPath;
where URLFriendly produces URL-friendly version of a title (a very nice example of it could be taken from Jeff Atwood's answer). This could produce URLs like:
/readBlog/2/how-to-install-visual-studio or
/readBlog/3/something-else.
You will want to look into URL Rewriting.
Maybe take a look at a Scott Gu Post on the subject.

Resources