tags:

views:

59

answers:

3

Is there a way to transparently pass URL parameters through web pages? I mean situation that when using redirects, already added parameters will be passed to new page without direct action of programmer.

For example:

  1. we entering page myPage1.aspx?param1=test
  2. performing Response.Redirect(myPage2.aspx)
  3. here I would like the parameter to be concatenated to URL and in result:
  4. page is redirected to myPage2.aspx?param1=test

Solution should be aware of that user can open more than one application instance that share one session (authentication). For example in one browser is opened myPage.aspx?param1=test and in 2nd browser is opened mypage.aspx?param1=test2.

We have already a few redirects (Response.Redirect) in the application so the perfect solution should not require to change existing code.

Can it be done?

A: 

You can use the Session object to do so, instead of copying parameters on the QueryString:

// in myPage1.aspx
Session["url"] = myUrl;


// in myPage2.aspx
var passedInUrl = Session["url"];

Another option is to use cookies, in a similar manner:

// in myPage1.aspx
Response.Cookies["url"] = "a url";

// in myPage2.aspx
var passedInUrl = Request.Cookies["url"]

Both ways are suited for small amounts of data, though you should probably encrypt cookies if you want to avoid tampering (or be able to discover tampering).

Oded
ok. but is there a way without session? and transparent to programmer? we already have few redirections in application and I would like them to stay intact.
Robert.K
@rkrass - you can use cookies. Why do you want to avoid session? It is great if you have small amounts of data that you want to persist between page requests.
Oded
@Oded - We would like to allow other web applications to pass parameters to our app. And if the parameter is passed I wouldn't like to loose it. In one session user can have opened more than one browser window so I think session parameter cannot be used.
Robert.K
@rkrass - You can store arrays and lists in sessions. Check if the session object is empty and if not, extract the list add to it and reassign to the session object.
Oded
@Oded - And what if user opens 2 browser windows with 2 different parameters? 2nd window will use parameter from session because it is already set (shared session). This is not behaviour I need.
Robert.K
@rkrass - I can't guess at what behaviour you need or don't need. You need to tell us - why don't you edit your question and add the exact details of the behaviour you need?
Oded
@Oded - I have added additional requirements in question.
Robert.K
@rkrass - Great, but this still doesn't explain what constraints you have. You say the solution "should be aware", but don't explain what that means. Aware how?
Oded
@Oded - I mean that we cannot use the same variable (session, cookie) to store the information because it is shared between browser windows. That is why I thought about URL in first place, URL is used per browser window.
Robert.K
A: 

You can use following if you dont want to use Session and just want to use Query String parameters

  1. You can loop through all your query string parameters like this

int loop1, loop2;

// Load NameValueCollection object.

NameValueCollection coll = Request.QueryString;

// Get names of all keys into a string array. String[] arr1 = coll.AllKeys;

string parameters = "";

for (loop1 = 0; loop1 < arr1.Length; loop1++) {

parameters += Server.HtmlEncode(arr1[loop1]) + "=" + coll.GetValues(arr1[loop1]);

for (loop2 = 0; loop2 < arr2.Length; loop2++) {

  parameters += Server.HtmlEncode(arr2[loop2]);

} }

its just basic idea. But you can loop through parameters without knowing the names.

To avoid writing code on everypage you can define a class like

public class QueryStringHelper { public static string GetQueryString(KeyValuePair querystring) { //get your string and return your query string using above method } }

then on every page you will have to do in page PREINTI Event

protected override void preinit()
{
       Response.Redirect("redirectpage.aspx" + QueryStringHelper(QueryString))
 }

I think copying this one event on everypage wont be a big issue.

AGAIN THIS CODE IS BASIC IDEA, THIS WILL NOT COMPILE

zish
yes, but is there a place to place above code to avoid rewriting old code that uses redirects?
Robert.K
zish
It'll still need adding this code on each page or its parent class. I would like to avoid that.
Robert.K
I have edited the basic code, see the code. if you want to redirect from each page, unfortunately you will have to do it on each page unless you 1. Make your own page class inherit from Page class and make basic preinit page and inherit all redirect page from your own page class and it will automatically redirect all pages inherited from your own class
zish
A: 

You could have a class that you instantiate at the top of each page that will handle this for you. I've written an example below. ++Note that this is untested, I just threw it together to give you an idea++:

public class QueryStringState
{
    private Dictionary<string, string> m_Params = new Dictionary<string, string>();
    private System.Web.UI.Page m_Page;

    // ctor
    public QueryStringState(System.Web.UI.Page _page, params string[] _persistArgs)
    {
        m_Page = _page;
        foreach (string key in _page.Request.QueryString.Keys)
        {
            if (_persistArgs.Contains(key))  // are we persisting this?
                m_Params[key] = _page.Request.QueryString[key];
        };
    }   // eo ctor

    // Resolve Url
    public string ResolveUrl(string _url)
    {
        // Resolve the URL appropriately
        string resolved = m_Page.ResolveUrl(_url);

        // Add our arguments on to the Url.  This assumes that they have NOT been
        // put on the query string manually.
        Uri uri = new Uri(resolved);
        StringBuilder builder = new StringBuilder(uri.Query);
        if(uri.Query.Length > 0)
            builder.Append("&");
        int counter = 0;
        foreach(KeyValuePair<string, string> pair in m_Params)
        {
            builder.AppendFormat("{0}={1}", pair.Key, pair.Value);
            ++counter;
            if(counter < m_Params.Count)
                builder.Append("&");
        };

        return(string.Concat(resolved, builder.ToString()));
    }
};

Let this class be a member of your page:

private QueryStringState m_QueryStringState = null;

And instantiate during initialisation, passing the names of any arguments you want to persist on the query string through pages:

m_QueryStringState = new QueryStringState(this, "param1", "param2");

Then you must make sure that any URLs that leave the page are passed through the ResolveUrl() method of this class:

myObject.HyperLink = m_QueryStringState.ResolveUrl("~/index/mypage.aspx");

As I stated, this is untested as I don't have the time right now to make sure it works exactly as intended but is to give you a general idea of how this might be solved.

Moo-Juice