I am building a content management intranet for my company. The website is based on DotNetNuke, and uses the excellent FreeTextBox control in order to enter HTML into the articles. One of the best features of
FreeTextBox is that you can easily add your own buttons and functionality to the control. For instance, the built-in function for adding images didn't meet my needs. My images are stored in SQL server, and require a custom
src property in order to retrieve the image. No problem - I added a new button to the control, and built a small aspx page that opens in a modal (popup) window. The popup window allows the user to choose an image to insert, or upload a new image to be inserted. But that's where my problems began.
Enter the IFrame
The trick to solving this problem is to wrap the aspx page in a "doorway" page. That is, you make another page that contains an
<IFrame> tag with its source page set to your aspx page. The aspx page then behaves normally within the given frame. Here is an example:
name="embeddedFrame" width="100%" height="100%" />
Great! Ok, so chances are that at this point you are good to go. But there is one problem left - what if you (like I) needed to pass a parameter to the aspx page? In my example above, I needed to pass the article number of the page I was working on, so that the page I was calling would know which images to display. When calling the aspx page, I would do something like this:
But how do pass the parameters from the host page to the
IFrame? Well, as the old saying goes, "You can't get there from here". Or can you?
Literal control. That's the little friend that saves the day in this case. Here is how it works. First, create your doorway page (an aspx page) and drop a
Literal control on it.
<form id="Form1" method="post" runat="server">
<asp:Literal id="Literal1" runat="server"></asp:Literal>
In the code behind (or in the script section), load up the literal control with the
IFrame tag, along with the parameters you need to pass:
Private Sub Page_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Dim myURL As String = Request.Url.ToString()
Dim ParamStart As Integer = myURL.IndexOf("?")
Dim Params As String = IIf(ParamStart > 0, _
myURL.Substring(ParamStart, myURL.Length - ParamStart), String.Empty)
If (Request.Params("Page") Is Nothing) _
Or (Request.Params("Page") = "") Then
Literal1.Text = "Error: No page was specified in the parameters."
Literal1.Text = "<IFRAME NAME='embeddedFrame'" & _
" WIDTH='100%' HEIGHT='100%' SRC='" & _
Request.Params("Page") & Params & "' />"
The code above is pretty short and well documented, but here it is in a nutshell. We grab the URL passed to the "doorway" page. The "
Page" parameter contains the name of the aspx page we wish to load into the
IFrame. If there are any additional parameters, we get those and store them in a string called
Params. Then, using the
Literal control, we dynamically create an
IFrame tag. The trick here is, now we can create the
IFrame with a
src value that contains not only the name of the aspx page we want to load in the
IFrame, but we can also add the passed parameters to that page. Cool.
Calling The Page
Now that we have our doorway page, we easily call the aspx page needed, and pass it the necessary parameters, all in one shot. In the example above, I was attempting to call the selectimage.aspx page and pass it an article number. Now, in order to make that work, I do this:
Where To Go From Here
That's pretty much it, although there is room for tweaking left, depending on how thorough you'd like to be. For example, you could easily turn this code into a simple control that could be dropped on a page, or even turn it into a base page to be inherited from. Now that you know the trick, all of these things are rather simple to do, and I leave those options to you to explore in more depth. If you are concerned about passing query strings in plain text as above, there was an excellent article on using secure query strings here.