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
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
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.
<BODY> tag of the Template that I’d created for the site at Combination “B”. The following is the holy line:
All that the above line states is that when the
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:
<A href="http://myserver:81/MySite/Lists/Support%20Issues/NewForm.aspx?QS=abc">http://MyServer:81/MySite/Lists/Support Issues/NewForm.aspx?QS=abc</A>
Then, this line is split into two from the question mark and the latter piece of text is taken and appended to the child
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.
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.
this.parent.id should also be possible, I guess ;-).