Introduction
This article provides a means of passing querystring from a .aspx page to another that is rendered inside a webpart within a Microsoft SharepointTM Portal Server. This article is useful for developers who develop custom webparts and create .NET web applications. The images that I've included will have certain text fudged out, to maintain secrecy of the client. But the concepts are pictured clearly.
To actually recreate this scenario, you'd need VS.NET & Microsoft Sharepoint Portal Server 2003 and MS SQL Server 2000 (in case you want the details in the database).
The problem scenario
There are times at work when you come across a problem, which no one else around you would have faced, and massive searches in Google yield little or no result for what you�re looking for. Well, then let me assure you that you�re not alone. There has been such a situation that I faced which I�d like to share with you.
To understand the problem and to appreciate the solution that I devised, I�d expect you to understand the way Sharepoint Portal Server� or even Windows Sharepoint services for that matter, works. To have an overview of the scenario, let me share the little technical knowledge that I have about these technologies just to assure myself that I�ve told about the environment before putting ahead the problem statement.
When you create a Sharepoint site and insert a �Page Renderer Webpart� that would eventually render any web page from any site that you�d mention as the source, then finally what you�d see at the browser is, the client-side code as generated by a �.aspx� file which Sharepoint puts out and within which is an iFrame
tag that renders the external source. In other words, the Page Renderer Webpart will be placed at the design level (let�s say you use FrontPage 2003), which in-turn during runtime, creates the iFrame
tag.
The reason behind the problem
The proof of concept (POC) that I am working on requires that I don�t use Sharepoint�s default workflow. Instead, almost everything is customized, including the workflow which is controlled by BizTalk� 2004. File uploads/downloads are done using Sharepoint APIs (these are fun to use, but are a pain when it comes to security). I gave a new look to the site that I created for this POC by creating a new Template file, with extension .dwt, and created a completely different menu that would nowhere near resemble the default Sharepoint menu. Almost all the graphics were created from scratch (Thanks to PhotoShop) excepting a few icons. Where most people take the trouble of creating web parts for each of the activity that need to plug in the Sharepoint site, I used the Page Renderer Webpart for 2 reasons:
- It makes it easy to change the content and/or its functionality without having to bother about re-deployment.
- It poses no security concern since the Page Renderer Webpart is registered as a safe control by default as it comes with Sharepoint, and one need not worry about manually registering a custom built control as safe.
The actual problem
Now, I am sorry if you�d assumed that the problem had been explained. But no, here it comes.
I created a Sharepoint site, which consisted of a Page Renderer Webpart that rendered a Login Page from another location from the same server, but a different port. Let�s call this Combination �A� as pictured in Figure 1.

Figure 1: A Sharepoint site running a default page with a �Page Renderer Webpart� (template) rendering a login page from another location, as indicated with a red outline.
This obviously means that at the client side browser, there would effectively be an iFrame
tag generated that renders the Login Page. When the user logs into the system, there are certain details that I need to get from the database and store in the session. Once this happens successfully, I am supposed to redirect to another page that shows certain options, and one of those is to redirect to a different site that would show a landing page with relevant menus. That other site is, once again, a Sharepoint site that holds a Page Renderer Webpart, which renders another set of �.aspx� pages that I built with a great sense of affection towards .NET. Let�s call this Combination �B� as pictured in Figure 2. The pages in Combination B would require the session variables that I populated after login event at Combination A. Now comes the challenge.

Figure 2: Another Sharepoint page where a querystring is passed, and with a �Page Renderer Webpart� rendering another page as indicated with a red outline. The challenge is to pass the querystring that the parent received and pass it to the page running inside the embedded Webpart.
Every little child who has worked with the web environment understands, that sessions cannot be passed on, as it is, between sites, whether or not they run on the same port. However, there is a work-around. You can pass the details in the form of a �Query String�. There is a hitch in this order as well. If you are running a site which is �inside� another (using iFrame
), then how on earth would you ask the �Parent� page to issue the querystring to the page running inside an iFrame
, when you pass a querystring to the �Parent� page which is running in a Sharepoint site? Remember, that you cannot alter the code of the Sharepoint page, even though it�s an aspx file. So the question of Request
ing for QueryString
from the parent page and adding it to the source information of the Page Renderer Webpart does not arise. I even tried entering <%=Request.QueryString(�QueryString�)%>
in the Sharepoint�s .aspx page (not the code-behind) at Combination �B�, in an attempt to pass it to the Webpart inside it (I used FrontPage 2003). It throws an error stating that this type of Server-side script is not supported.
The solution
After a lot of experimenting, I finally found a solution. The reason the letter �a� is bold in the previous line is because, I�d like to emphasize on the fact that this solution is by no means the only way of achieving the desired result. You could have a better solution, and if you do, then please do let me know. The solution is simple. One line of JavaScript code saved my day.
Like I�d mentioned before, one would not be able to alter the code-behind of the .aspx pages in Sharepoint, but can certainly add JavaScript code to the .aspx page. The line that I added was to the <BODY>
tag of the Template that I�d created for the site at Combination �B�. The following is the holy line:
onload=�javaScript:window.document.all[�iFrame�].item(0).src
+=window.parent.location.pathname.split(�?�)[1];�>
All that the above line states is that when the body
onload()
event of this page occurs, then find the first occurrence of the iFrame
tag in the document, and to its Source (src
) attribute, append the rest of the text from this window�s location after the �?�. For instance, if the location information is something like:
http://MyServer:81/MySite/Lists/Support Issues/NewForm.aspx?QS=abc
Then, this line is split into two from the question mark and the latter piece of text is taken and appended to the child iFrame
�s src
attribute.
Once this is achieved, in the code-behind of the .aspx page that is being rendered inside the iFrame
, you can include Request.QueryString(�QS�)
to fetch the parameter passed from Combination A.
Improvement
If suppose there are too many details that you wouldn�t want to pass between the Combinations, then you may use a table in a database to hold all the details and a GUID that differentiates between each record. You would generate this GUID at the time before redirecting to Combination �B� and save the details in the database with the GUID being the Primary key. To generate the GUID, use GUID.toString()
. Once the GUID is passed to Combination �B� as querystring, use it to fetch the details that you had in Combination �A� from the database and re-populate the session. When the session at Combination �B� ends, delete the details from the database using the GUID again as the key.
Conclusion
Though this issue was solved with a line of JavaScript code, there would�ve been another way of resolving it. I�ve heard that every browser when started has its own unique ID. I did not find a means of getting that information. If there were a means of capturing that, then that ID (which I presume would be unique) could�ve been used instead of the GUID and the hassle of using querystrings could have been avoided. You could save all the details from Combination �A� in the database as mentioned earlier, with the browser�s ID as the primary key, and at Combination �B�, fetch the details back from the database using the browser�s ID as the reference. There could be some minor issues with this technique as well. When a user opens a link from the site in a new window, then that window will have its own unique ID. Then there would not be a matching record in the database. If all this could be done, then probably something like this.parent.id
should also be possible, I guess ;-).