Sub Trace(ByVal errorString As String, Optional ByVal x As String = "title not set")
System.Web.HttpContext.Current.Trace.Write(x)
System.Web.HttpContext.Current.Trace.Write(errorString)
End Sub
Function PG() As HttpContext
'Ex:
'PG.Response.Redirect("...")
Return System.Web.HttpContext.Current
End Function
Function AP(ByVal x As String) As String
'Ex:
'MailMessage.To.Add(New MailAddress(AP("SupportAddress")))
Return System.Configuration.ConfigurationManager.AppSettings(x)
End Function
Dim btn As New Button btn.PostBackUrl = "www.insert-title.com" btn.OnClientClick = "if(!validate())return false;" btn.Text = "Submit"
Function Notta(ByVal x As Object) As String
Dim ret As String
If (x Is DBNull.Value) OrElse (x Is Nothing) OrElse (x Is String.Empty) Then
ret = ""
Else
Try
ret = CStr(x).Trim
Catch
ret = ""
End Try
End If
Return ret
End Function
As a preface, this is really only a solution for those of us who do not have a dedicated or VPs server. If you have access to the IIS Management console there are much better ways to accommodate the need for URL rewriting.
I am going to demonstrate a simple way to implement this, but there are a number of much more complex ways to utilize this code.
You have an ecommerce site and want to clean up your URLs a bit. A call to products.aspx?ID=123 is not quite as good as widgets.aspx.
No Problem.
The solution is a Global.asax file.
So this file goes into the root of your .NET application.
It starts like this
<script language="vbscript" runat="server"> Sub Application_BeginRequest(Sender As Object, E As EventArgs) ...... End Sub </script>
The Application_BeginRequest is a lot like the page_load event in your standard .NET code except it starts with the application not the individual page.
And as an example if we popped this into our application and made it read
<script language="vbscript" runat="server">
Sub Application_BeginRequest(Sender As Object, E As EventArgs)
response.write ("Hello world")
End Sub
</script>
Then from there on every page that loaded within this application would have the "Hello World" line at the top of the page.
Okay with me so far? Great!
Whats next... well we're talking about rewriting URLs so we need to know how to look at the URL itself.
<script language="vbscript" runat="server"> Sub Application_BeginRequest(Sender As Object, E As EventArgs) Dim httpContext As System.Web.HttpContext = HttpContext.Current Dim currentURL As String = CurrentURL.Request.Path.ToLower() response.write (currentURL) End Sub </script>
Done, now we are showing the URL in place of Hello World, it's really the path rather than the URL, so we don't have to worry about splitting out a bunch of /'s. We should be seeing the path of the current page relative to the global.asax file or the Application root.
I hope I am not losing you here - it doesn't matter, stick with this and you'll get it in the end.
So we've taken our URL and converted it into a string... so we have "products.aspx?ID=123" at the top of our page and it really isn't helping anybody yet...
All we need to do now is instead of calling "products.aspx?ID=123" let's call "widgets.aspx"... and then all we need to do is tell it that "widgets.aspx" = "products.aspx?ID=123"
Here goes.
<script language="vbscript" runat="server">
Sub Application_BeginRequest(Sender As Object, 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
</script>
Thats it. One thing to mention here is that you can really, really expand on this.
clicky - widgets.aspx
This is really very simple but I have been asked a number of times how I do this on some of my sites.
This walk-thru will demonstrate how to create a web application project using the IDE, create a layout using frames with Microsoft FrontPage 2003, and configure the project for later being ran and debugged while not compiled with the Codebehind model (that by default relies on a compiled DLL.)
Bringing back the Codebehind model on a temporary basis when editing the project will also be demonstrated. This way some of the niceties that the IDE naturally provided by default can be once again made available like working with the pages in Design view and Code-Completion.
Download the sample project used in this demonstration
View the project conversion macros used in this example
As ASP.net and the Microsoft Development Environment 2003 provide a means for developers to create object-oriented, content-separated code with an IDE that allows for rapid application development and writing server-side code that responds to client-side events easily, there have been some inherit problems with the approach. Obviously many developers would jump at making any transition needed to be able to develop this way and many have already done so.
However, there is a flip-side to this too as with anything new, the grass is sometimes greener on the other side. Many developers have avoided using this IDE due to obstacles that stood in their way. Often the HTML created by the design view of this IDE (not to mention others as well,) was not acceptable to developers and they've resorted to a "notepad" style of coding and have been doing so for quite some time now. Also, the nature of the classic ASP world tended to be inter-mingling server-side code with the HTML content on a web page causing many developers to be used to a raw development style as a result. Even though this particular IDE has offered a new coding style to be used, developers feel they are being forced down some pathways they have trouble accepting or getting around.
One of these pathways just mentioned, is compiling all of the class files for each of the web pages of the site into a DLL. While this has its benefits, it also has bothered many developers when they were used to being able to jump in and make a quick change on the fly using any text editor of their choosing and not having to re-compile a DLL. Although I am not personally against using a DLL all together, I like to know my options.
I hope this article will be informative and demonstrate some techniques that maximize the use of the IDE and that possibly may not be well known.
I'll start by creating a Visual Basic Web Application project using Microsoft Development Environment 2003. This step will create a virtual directory with my solution's name and create all the needed project files to get up and running. These files include a global application file, a default .ASPX web page, and a .CSS stylesheet just to name a few. Matching .VB source code files have been created for the .AS?X file types being the Codebehind files in this project. Typically when the editing of these content and code files is done or at a good stopping point, the project is compiled,and each of these classes defined in the VB files gets compiled into one project-level DLL that supports the entire application at run-time. This DLL is saved to the Bin folder in the directory where the project files have been created. My demonstration in this article is not going to take that step and will not compile the code into a DLL.
I first began by launching the Microsoft Development Environment 2003. A couple of macros have been created to help facilitate my using the IDE for this demonstration. I will later discuss those macros in further detail.
First we shall create a new web application project (File - New - Project...)
I named this web application Base and clicked [OK].
Later in this demonstration I change the project properties to default the creation of web pages in FlowLayout mode instead of GridLayout. I also later changed the default client scripting language to VBScript. These settings are my personal preference; however, for the sake of this demonstration, you may want to make them in this particular project.
Now that the project and virtual directory have been created, I next renamed the webform to Default from the solution explorer. Then I right clicked on the page and selected View HTML Source. Inside the HTML source, I changed the reference for the Inherits attribute to:
Inherits="Base.DefaultClass"
The web page is now set to inherit from the class DefaultClass which in-turn inherits from System.Web.UI.Page. I still needed to open the VB code file and change its class name to DefautlClass.
I now had the base structure for the default web page created and ready for content. Considering how later these source files will not be ran using the Codebehind model, I needed to add 1 Import statement for the Global.asax.vb file right away. For the purposes of this demonstration using this project, no other Import statements will be needed.
Now I decided to use Microsoft FrontPage 2003 to create a frames page. Afterwards I copy some of the HTML it generates to my Default.aspx page.
(File - New...) and then I clicked More page templates... and then I selected Header, Footer and Contents.
The following frames page was created:
Next I opened the code view for this page, and changed some of the settings of the frames.
Now I copied the following HTML to the clipbboard so I could paste it into my Default.aspx page.
Here I pasted the HTML over the following text inside the Default.aspx page.
Next I changed the page title to Base.
Now I began creating the other .ASPX web pages in the project that will be loaded into these different frames. I right clicked the project from the solution explorer to add a web form to the project (Add - Add Web Form...)
At this point I determined that except for the default page, I'd name all web pages with the web prefix. So I opened the Default.aspx in HTML Source view again and changed these filenames to webHeader.aspx, webSidepanel.aspx, etc.
Before I continued adding the rest of the pages, I decided this would be a good point to stop and change a couple of project-level properties. (Project - Properties...) and then (Common Properties - Designer Defaults)
I changed the Page Layout and Client Script Language settings that will be used during the creation of every new web page created by the IDE in this project. Since the last web pages were created before these settings were changed, I will manually change them soon.
With these settings in place I proceeded to create the rest of the .ASPX pages that will be used for the frames.
For each of the frames I began typing some text into them so when viewing these frames later in Microsoft Internet Explorer I'd have a good idea of what I was looking at.
As I came to the webHeader.aspx file from the solution explorer, I saw this was one of the frames I needed to change manually and so I right clicked the page and selected Properties...
Here I changed the Page Layout and Default scripting language settings and clicked [OK]
Now I have all the pages created and saved and I'm ready to view them from Microsoft Internet Explorer.
I want to run this project without compiling the pages to a DLL so I shall NOT hit F5 at this point; instead I will use my macro to convert these files so they no longer use the Codebehind model. Even if F5 is accidentally pressed, no real harm will be done, but a DLL will be created. When the pages are changed from Codebehind to Src, the DLL will be ignored when ran anyways. This macro ToSrc will do the following:
1. Close all open files in the IDE (saving them.)
2. Find and replace in all .AS?X files the Codebehind attribute to Src.
3. Assume the project name involved has the same base name as the solution, and replace all of the Inherits attributes in these same files, removing the project name from the setting.
4. Afterwards, all the files will be saved.
Note: This macro and the other described later were created by me (not Microsoft) and is for use at your own risk. The general things to consider when using these macros is that they are intended for a solution having only 1 project that are each named the same and having source files not set with read-only attributes like is often the case when the files are under source control using Microsoft Sourcesafe. These macros have been created to give a general idea of the needed changes going to and from the Codebehind model while still making good use of the IDE.
So the ToSrc macro has now been executed. The web application can now run using IE and no compilation needs to occur.
I next decided to modify some of the settings for the virtual directory from Internet Information Services (found under Administrative Tools) before continuing.
Here I typed the name Base for the application name, selected High (Isolated) for the Application Protection setting, and further continued some changes after clicking Configuration...
I changed the Debugging Flags to make them both enabled. Afterwards I clicked [OK] to both this dialog and the previous one. These settings allow for me to debug this application from a manual approach but are not needed for the virtual directory during production use. Afterwards, I still needed to change one more setting in Component Services (also found under Administrative Tools.) This last setting can only be applied to an application configured with High application protection and is to allow the user (security-wise) to attach to the running process from the Microsoft Development Environment 2003.
Here I located my application IIS--{Default Web Site//Root/Base} and selected Properties...
Under the Identity tab, I changed the account that the application would be run under. After clicking [OK] to this, I will be able to attach to the running process (when it is running from IE for example.) Now that I made these changes, I decided to run the project from IE.
Now that the site has run without having compiled the DLL and the virtual directory is set to be debugged, I next made some changes to the content web page so I can further demonstrate the use of the IDE and debugging the application. Here I decided to run the other macro I created called ToCodebehind. The purpose for this macro is to change the files back to the Codebehind model so that the IDE will be friendlier with the pages, giving me back Design view, auto mapping to the events for the objects from the Design view, and Code-Completion in the code files. This macro ToCodebehind will do the following:
1. Close all open files in the IDE (saving them.)
2. Find and replace in all .AS?X files the Src attribute to Codebehind.
3. Assume the project name involved has the same base name as the solution, and replace all of the Inherits attributes in these same files, adding the project name to the setting.
4. A piece of self-cleaning code to ensure that if this macro has run several times, that the project name is not added multiples times in these attribute values.
5. Afterwards, all the files will be saved.
Note: This macro was created by me (not Microsoft) and is for use at your own risk. The general things to consider when using these macros is that they are intended for a solution having only 1 project that are each named the same and having source files not set with read-only attributes like is often the case when the files are under source control using Microsoft Sourcesafe. These macros have been created to give a general idea of the needed changes going to and from the Codebehind model while still making good use of the IDE.
So the ToCodebehind macro has now been executed. The source files can now be opened in Design view, objects from the toolbar be added to the pages, and events for those objects be attached. The coding for these pages and the server-side events can be done with full Code-Completion and life is good. After opening my webContent.aspx file, I added a button and a text box from the toolbar to the page and I changed the bgColor of the document to aliceblue which in this case was transformed to a hex value in the Properties toolbar.
Now entering the code view after having double clicked the button from Design view. I'm ready to "code away."
Here I decided to add another Imports statement because it may come in handy later and added a line of code to run for the button's click event.
Now edits have been made, and I run the ToSrc macro again. Going to and from the Codebehind model isn't necessary every time a change is to be made, but it will often be the desirable approach when several changes from Design view are desired and/or alot of code will be added or changed to the source files.
Now I refresh the page out of IE.
Before I click the button and see the textbox updated with the date and time, I figure this is a good time to demonstrate debugging the page with the IDE attached.
I click Debug - Process... in the IDE and select the aspnet_wp.exe process that is handling my web application and then I click [Attach...] If debugging an ASP.net application, I will use the Common Language Runtime option and for classic ASP applications, I'll have the Script option checked. The process that runs the classic ASP apps, at least on Microsoft Windows XP, is the dllhost process. Anyways, I select these items, click [OK], and then am attached to the process for my application. Too bad I'm not seeing the page listed in the running documents like I'm used to with classic ASP sites.
Later I'll demonstrate adding these code files to the solution; however, at this point, I just open the code file I want to debug.
With this project open and being attached to the running process, this file opens in debug mode (read only) so I can now step trace, place breakpoints, and debug the code.
Now I click the button from the page and the breakpoint in the IDE is hit.
I added the text property of the textbox to the watch window and stepped into the code passing the statement that changed its value and see it changed in the watch window.
Now I hit F5 to resume running the page and finish the web request and IE gets refreshed and updated.
See all this and no DLL!
Remember if you try and open a file in Design view from the IDE that is linked to a code file using Src instead of Codebehind, you will generally see this following error. Afterwards, the page will still open only for HTML Source view while Design view will be disabled. These files need their page declarations changed and be saved and closed before being re-opened in Design view. The macros shown above help ease this process.
Here I add the VB files to the solution so they can be easily accessed when not using the Codebehind model.
Remember that when using the macros, it is important to have the main project selected and highlighted from the Solution Explorer, so the "replace in all files" (for the current project) happens correctly.
One additional remark is that if this approach for coding a web application is liked and source control will be used, one consideration would be to change the macros to not work at a project level but rather a file level, so pages could be checked out from source control, converted (via a macro,) edited, saved, tested, and then converted again (using another macro) before the file is checked back in.
I hope you have enjoyed this journey in the ASP.net world. Happy coding!
Our original Contact Form was based on the standard ASP spaghetti code posting back to itself and using the ASPMail component.
This was definitley one of those instances where I got tired of reading pretty quickly. It seems there are many, many options when creating forms, checkboxes, and emails with .NET
I read these two simple articles and sample files and went about rewriting this page pretty quickly, using some of the knowledge I had already picked up in the previous articles.
CheckBoxList Web Server Control
How to send an email in ASP.net
The second article there was simply this easy ASP.NET Email script
While this was useful, it didn't answer all my issues, just got me started. I also picked up that I didn't have to use the StringBuilder Class in order to build up a string as I had thought before. This time I simply used
So in essense my previous example of how to build a string could now also be
This made a lot more sense to me
Not sure if i used all the proper techniques here, but I essentially put the entire form inside <asp:label ID=contactForm></asp:label>
Then a Thank You Message in another label tag.
the "If.IsPostBack" means "If the user has posted"... I think you'll get the rest
Anyways here's the code I ended up with
And here's a cleaner copy of almost the same thing, but with less emphasis on design and fewer fields
So the issues at hand are how does ASP.NET handle Arrays and the File System Object of ASP Classic....
I sought out answers...
references so far:
After reading all this and some others I will list below, I have decided to use the ASP.NET datagrid instead of the Array I used in the original script. I did start off writing an ASP.NET script using the array which was more true to the original script, but never got a real grip on how to page through the DataList. The built in paging in the DataGrid is just awesome and too good to pass up.
While this solution works for us I still want to rebuild the very customizable imageBOX as well as further develop the look and feel of the datagrid. Need "First" and "Last" links and the ability to add different image types.
Although, in my reading I am finding it is not that hard to build the First Page and Last Page links, I am somewhat disappointed that this functionality isn't already built in to the datagrid. It would seem so natural in conjunction with the functionality that is already there... maybe this was a rushed job? Is there some reason this wasn't added in ?
As a side note I talked extensively with Dan Kirkwood Jr., of Eagle Innovations, Inc., about this topic, as he is as far as I know the only ASP.NET guru I personally know. Here's a a bit of that Conversation
At the heart of our website is this single file/script which calls all other pages and allows us to incorporate new pages into our site without a lot of revamping or reconfiguring.
This file was discussed in Part 1 of the article and here is what I did.
From the original code below:
I created the following
I also updated the default.aspx file to include the new xml.ascx (formerly xml.asp) user control to read
Based on two articles I read, one from 4guysfromrolla.com, ASP.NET Unleashed (c/o Dan Kirkwood Jr. of Eagle Innovations). I was able to develop the new code. One thing to note is that there doesn't seem to be a lot of support when it comes to String Manipulation in ASP.NET available on the web, so I did have to turn to the book for that, which I must say seems to be the best reference for this feature as of yet.
So, essentially, I removed the "XMLHTTPObject" and began working with the "WebClient()" class.
I used the "StringBuilder" class to add my desired extension to the "strURL" creating
One thing I have not yet handled was the "File Not Found" issue, this was originall handled with ASP Classics FileSystem Objectr, I will have to find a solution to this before all is done.
At first this class for building up a string seemed a bit alien to me, but after using it a bit, it isn't really all that different from what you may have already done in classic ASP
Another issue I ran across was the lack of support of the ASP Classic function "Instr"
Where this would have worked in Classic ASP
I now had to use:
Not a huge difference, but we still seem to be lacking in documentation about these string manipulation features for .NET
Next Task: Converting some of the dynamic applications on the site from ASP Classic to ASP.NET
I started by readng a bit of this wonderful article: http://authors.aspalliance.com/anjum/ASPMigration.aspx
Based on the information in that article I've rewritten the default.asp page from
And renamed the file from default.asp to default.aspx.
One thing I noticed is that the inclusion of aspcompat="true" led me to believe that it would be needed in order to process some of the older ASP code in these pages, but even without everything is okay so far. (leaving it nonetheless)
I've skipped the xml.asp tranformation for now, attempting to get the easier solutions in hand, first.
At the top of the open.asp page which I renamed open.ascx making it a user control I added the following
And where I used to have the leftBar.asp included I replaced
At the top of the open.asp (now open.ascx) I used to have the following
This gave me the error
Server Error in '/' Application.
----------------------------------
Compilation Error
Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately.
Compiler Error Message: BC30800: Method arguments must be enclosed in parentheses.
Upon removing the offending code, which turned out to be
all was well, but this is something I will have to return to, in order to find out exactly what ramifications it has on the caching of the pages.
For the record I am not a coding guru, like Scott Mitchell or Stephen Walther, or Jeffery Zeldman or any of those other guys. I am however a hands on master. I can get the job done "NOW"
I work everyday in an industry that is heavily saturated and still come out ahead every time. Because I deliver the goods one way or the other.
I've been guilty of writing spaghetti code, using too many session variables and not enough stored procedures.
Skillwise, I'm capable enough to read some documentation and get out of it what i need. CSS,ASP and server-side vbscript are my primary specialties, outside of that I am pretty good with a handful of graphics apps and development tools(Mostly MX)
I understand the bare minimum of javascript and use it only as a client-side form validation tool. I have no intention of writing any of this ASP.NET in any language outside of VB, so all you C# users out there, either need to get good at changing from VB to C# (which is generally , not too complicated) or read a different article.
I do not intend to rewrite this article over and over, so you'll see as I learn from my mistakes in real-time. If one method becomes more efficient that another you won't see me changing it on all previous sections of the article. This is an evolution of someone who knows very little about ASP.NET, but has a strong understanding of Classic ASP. If this sounds like you, you'll appreciate this article. If not, you'll think it's a waste of time.This site currently consists of a very simple file structure and few databases which is why I think it is a perfect project for learning ASP.NET step by step while attempting to achieve all the same results.
Currently almost every page is called from the default.asp page which looks like this:
The open page consists of all the meta info, calling the style sheet and top half of the graphical layout.
The open page also has an include statement for the leftBAR.asp which constitutes all the navigation at the left hand side of the page.
The xml.asp page is really the heart of organizing this website. Using the XMLHTTP Object I develop page upon page without the need of going through a lot of trouble to add it to the site.
Here is the xml.asp code - -it may come in handy for you.
In essence what this means is that
The xml.asp file picks up the content of that page and returns it in between open.asp and close.asp.
Of course, a large concern is how ASP.NET will handle the current CSS that we apply to this site. This will need to be addressed as we move along
Here's the gameplan -
Start with the big picture get the fundamentals of the site sorted out and drill down to each single page.
Also - I dont want to rely on any GUI/IDE (i.e., Dreamweaver, VS.NET, etc.) to make any changes, so all coding will happen in my favorite coding tool, Textpad