Rewrite URLS using global.asax - asp.net

I'm trying to make some friendlyurls in my vb.net (.net 4) project and I'm trying to do it using something I read about global.asax and Application_Beginrequest but I can't get it to compile.
Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
Dim httpContext As System.Web.HttpContext = httpContext.Current
Dim currentURL As String = currentURL.Request.Path.ToLower()
If currentURL.IndexOf("widgets") > 0 Then
objHttpContext.RewritePath("products.aspx?ID=123")
Else
objHttpContext.RewritePath(httpContext)
End If
End Sub
Above is what i'm trying but it's erroring on the objHttpContext. is there another method? Ideally once I get the above method working I'm going to be attempting to use a database call to work out the URLs. So any suggestions in that direction will also be very welcome. I'm trying to get away from having to install anything on IIS as it's a load balenced enviroment that I'd rather not install something on every server.
Thanks
Tom

You should access HttpApplication.Context. Here is how I do it (C#):
string reqPath = Request.Url.AbsolutePath;
if(reqPath=="/")
newPath="/Pages/PL/Main.aspx";
if (newPath != "")
HttpApplication.Context.RewritePath(newPath);
As I can see in documentation you should be able to use exactly the same syntax to access the context in VB.NET.
You could also use II7 url rewrite module if you really wanted.

Why do you want use rewriting, when you can do it really easy using asp.net routing?
Please, look at the following link for more info:
http://msdn.microsoft.com/en-us/library/cc668201.aspx

Related

How to use caching?

Basically, I retrieved a dataset and I want to cache it in the server memory for one month. So I don't need to call the query again and again when running the page within this month.
I did some research and think http://msdn.microsoft.com/en-us/library/system.web.caching.cacheitemremovedcallback%28v=vs.110%29.aspx is the way to do the cache, basically i modified the sub codes to fit into my application
Public Sub RemovedCallback(k As String, v As Object, r As CacheItemRemovedReason)
itemRemoved = True
reason = r
End Sub
Function AddItemToCache(cacheKey as String, ds as Dataset)
itemRemoved = False
onRemove = New CacheItemRemovedCallback(AddressOf Me.RemovedCallback)
If (IsNothing(Cache(cacheKey))) Then
Cache.Add(cacheKey, ds, Nothing, DateTime.Now.AddMonths(1), TimeSpan.Zero, CacheItemPriority.High, onRemove)
End If
End Function
There are quite a few errors in this piece of code. One of the error is for Cache(cacheKey) says that " Cache is a type and cannot be used for expression"? where did i do wrong?
Sounds like you're using IIS cache. First of all, if this is your route - if you have an assemblies that may use cache (when available), you need to create Caching assembly in which you check for HTTPcontext. If it is null - you are running outside of IIS and caching will not be available.
A good alternative is to download Enterprise Library Caching blocks if you working with framework up to 3.5. If you use FW4.0+ you use system.runtime.caching. This way cache will be available always. There is also AppFaric and some third party cache implementations but this is probably outside the scope for you.
For your error, it sounds like your identifier Cache [your code is not showing how you assign it] is actually a type. That is if you did this
If Integer Is Nothing....
What you need is to use is syntax
System.Web.Caching.Cache.Add...
Now, this is instance. So, what you can do is
Dim c as Cache = System.Web.Caching.Cache
c.Add(....

How to fix Error executing child request?

I am building an asp.net app and I keep getting this error while trying to transfer pages:
Error executing child request for Edit_PropertyData.aspx
I have no clue what's causing it or how to fix it, any help would be greatly appreciated!
Here is the Page_Load event of Edit_PropertyData.aspx
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
cmdChangeMaterial.Attributes.Add("onclick", "CheckSaveStatus();")
cmdEditMaterial.Attributes.Add("onclick", "CheckSaveStatus();")
If Session("Mode") Is "Edit" Then
cmdEditMaterial.Enabled = True
cmdSaveData.Enabled = True
Else
cmdEditMaterial.Enabled = False
cmdSaveData.Enabled = False
End If
pnlMain.Visible = True
pnlMain.Height = Unit.Pixel(650)
End Sub
Server.Transfer doesn't allow you to do a lot of things. You're probably trying to use it to pass query string parameters or some such. But you don't need that - the URL doesn't change in the target of the transfer, so you've still got the original query string. This can be both a good and a bad thing, depending on how you use it :)
You probably want to use a different transfer method instead - if you're inside a HttpModule, have a look at HttpContext.Current.RewritePath.
What have you tried so far? A quick search gives a number of similar error messages with proposed and accepted solutions.
Server.Transfer throws Error executing child request. How to resolve?
http://forums.asp.net/t/1489436.aspx?Server+Transfer+Error+executing+child+request
http://support.microsoft.com/kb/320439
You don't mention what you're transferring from, but I suspect Response.Redirect or HttpContext.Current.RewritePath will be a better alternative for you.

Creating a dynamic graphic in asp.net

I am busy creating a control in asp.net. The control consists of some text and an image. The image will be used to display a graph. The control gets the data for the graph by reading it from a database. It seems I have two options to display the graph in the image box. First, I can create a jpg from the data and save the file on the server. I can then load this file into the image box. I think this would cause a problem if various users try to access the site at the same time, so I don't think it is a good option. The other options is to create a file called output, that outputs the graph like this: objBitmap.Save(Response.OutputStream, ImageFormat.Gif)
I can then display the image like this in my control: Image1.ImageUrl = "output.aspx"
The problem that I am facing is how do I get the data from my control to the output page? As far as I know it is too much data to pass as a parameter. If there is another better method of doing it, please let me know
Thanks
You can write the image content to the response of output.aspx. Something like this (taken from one of my existing GetImage pages:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim strFilename As String
strFilename = Request.QueryString("filename")
Dim strPath As String = AppSettings("ProxyImageSavePath") & strFilename
Response.Clear()
Response.ContentType = "image/jpeg"
If Not IO.File.Exists(strPath) Then
'erm
Response.Write("file not found")
Else
Response.WriteFile(strPath)
End If
Response.End()
End Sub
Edit: I've just realised this may not be the solution you're looking for; Your webserver should be able to cache this though.
You need handlers. See in this article, Protecting Your Images, section "Creating the ImageHandler HTTP Handler", you'll find the code how to write the handler, so it outputs an image. You don't need all, it's only an example.
You also need to register the handler in the web.config.
To reference it Image1.ImageUrl = "handler.ashx?graphdata=xxxx". Use QueryString to get the data source to generate the graph.

ASP.NET create a page dynamically

I am dynamically generating HTML which is stored in a string variable.
I would like to open a new window with a new page created from this HTML.
This seems too simple, but I just cannot find the solution.
I am using ASP.NET 3.5 and VS2008.
Thanks,
Paul.
Best idea would be to create an http handler, register it in your web.config file to handle the various request paths that you need to have dynamic content for, and then detect the content to display based on HttpContext.Current.Request.Path.
This way you don't have to save any files, and you write from your string variable to the output stream
You can try this in your new page:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
HttpContext.Current.Response.Clear()
HttpContext.Current.Response.ClearHeaders()
HttpContext.Current.Response.ClearContent()
HttpContext.Current.Response.ContentType = "text/html
HttpContext.Current.Response.Write(YourString)
HttpContext.Current.Response.Flush()
HttpContext.Current.Response.End()
End Sub
Create an .ashx page that takes a query string, e.g. pagebuilder.ashx?pageid=12345
The purpose of this page is simply to lookup in a session id based on the pageid query string. e.g.
var page = Session["PAGE_" + QueryString["pageid"]].ToString();
Response.Write(page);
On the page that generates the html in a variable, store the variable in Session at Page_Init
` ["PAGE_12345"] = generatedHtml;
Then on Page_Load, generate a javascript that opens to the url pagebuilder.ashx?pageid=12345.
That's it. You will be able to open your newly generated html in another window.

Best way to handle URLs in a multilingual site in ASP.net

I need to do a multilingual website, with urls like
www.domain.com/en/home.aspx for english
www.domain.com/es/home.aspx for spanish
In the past, I would set up two virtual directories in IIS, and then detect the URL in global.aspx and change the language according to the URL
Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
Dim lang As String
If HttpContext.Current.Request.Path.Contains("/en/") Then
lang = "en"
Else
lang = "es"
End If
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(lang)
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(lang)
End Sub
The solution is more like a hack. I'm thinking about using Routing for a new website.
Do you know a better or more elegant way to do it?
edit: The question is about the URL handling, not about resources, etc.
I decided to go with the new ASP.net Routing.
Why not urlRewriting? Because I don't want to change the clean URL that routing gives to you.
Here is the code:
Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
' Code that runs on application startup
RegisterRoutes(RouteTable.Routes)
End Sub
Public Sub RegisterRoutes(ByVal routes As RouteCollection)
Dim reportRoute As Route
Dim DefaultLang As String = "es"
reportRoute = New Route("{lang}/{page}", New LangRouteHandler)
'* if you want, you can contrain the values
'reportRoute.Constraints = New RouteValueDictionary(New With {.lang = "[a-z]{2}"})
reportRoute.Defaults = New RouteValueDictionary(New With {.lang = DefaultLang, .page = "home"})
routes.Add(reportRoute)
End Sub
Then LangRouteHandler.vb class:
Public Class LangRouteHandler
Implements IRouteHandler
Public Function GetHttpHandler(ByVal requestContext As System.Web.Routing.RequestContext) As System.Web.IHttpHandler _
Implements System.Web.Routing.IRouteHandler.GetHttpHandler
'Fill the context with the route data, just in case some page needs it
For Each value In requestContext.RouteData.Values
HttpContext.Current.Items(value.Key) = value.Value
Next
Dim VirtualPath As String
VirtualPath = "~/" + requestContext.RouteData.Values("page") + ".aspx"
Dim redirectPage As IHttpHandler
redirectPage = BuildManager.CreateInstanceFromVirtualPath(VirtualPath, GetType(Page))
Return redirectPage
End Function
End Class
Finally I use the default.aspx in the root to redirect to the default lang used in the browser list.
Maybe this can be done with the route.Defaults, but don't work inside Visual Studio (maybe it works in the server)
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Dim DefaultLang As String = "es"
Dim SupportedLangs As String() = {"en", "es"}
Dim BrowserLang As String = Mid(Request.UserLanguages(0).ToString(), 1, 2).ToLower
If SupportedLangs.Contains(BrowserLang) Then DefaultLang = BrowserLang
Response.Redirect(DefaultLang + "/")
End Sub
Some sources:
* Mike Ormond's blog
* Chris Cavanagh’s Blog
* MSDN
Use urlrewriteing.net for asp.net webforms, or routing with mvc. Rewrite www.site.com/en/something.aspx to url: page.aspx?lang=en.
UrlRewriteing.net can be easily configured via regex in web.config. You can also use routing with webforms now, it's probably similar...
with webforms, let every aspx page inherits from BasePage class, which then inherits from Page class.
In BasePage class override "InitializeCulture()" and set culture info to thread, like you described in question.
It's good to do that in this order: 1. check url for Lang param, 2. check cookie, 3. set default lang
For static content (text, pics url) on pages use LocalResources,or Global if content is repeating across site. You can watch videocast on using global/local res. on www.asp.net
Prepare db for multiple languages. But that's another story.
I personnaly use the resources files.
Very efficient, very simple.
UrlRewriting is the way to go.
There is a good article on MSDN on the best ways to do it.
http://msdn.microsoft.com/en-us/library/ms972974.aspx
Kind of a tangent, but I'd actually avoid doing this with different paths unless the different languages are completely content separate from each other.
For Google rank, or for users sharing URLs (one of the big advantages of ‘clean’ URLs), you want the address to stay as constant as possible.
You can find users’ language preferences from their browser settings:
CultureInfo.CurrentUICulture
Then your URL for English or Spanish:
www.domain.com/products/newproduct
Same address for any language, but the user gets the page in their chosen language.
We use this in Canada to provide systems in English and French at the same time.
To do this with URL Routing, refer to this post:
Friendly URLS with URL Routing
Also, watch out new IIS 7.0 - URL Rewriting. Excellent article here http://learn.iis.net/page.aspx/496/iis-url-rewriting-and-aspnet-routing/
I liked this part
Which Option Should You Use?
If you are developing a new ASP.NET Web application that uses either ASP.NET MVC or ASP.NET Dynamic Data technologies, use ASP.NET routing. Your application will benefit from native support for clean URLs, including generation of clean URLs for the links in your Web pages. Note that ASP.NET routing does not support standard Web Forms applications yet, although there are plans to support it in the future.
If you already have a legacy ASP.NET Web application and do not want to change it, use the URL-rewrite module. The URL-rewrite module allows you to translate search-engine-friendly URLs into a format that your application currently uses. Also, it allows you to create redirect rules that can be used to redirect search-engine crawlers to clean URLs.
http://learn.iis.net/page.aspx/496/iis-url-rewriting-and-aspnet-routing/
Thanks,
Maulik.

Resources