【问题标题】:How to transparently pass URL parameters from page to page?如何在页面之间透明地传递 URL 参数?
【发布时间】:2011-05-01 18:50:49
【问题描述】:

有没有办法透明地通过网页传递 URL 参数?我的意思是在使用重定向时,已经添加的参数将被传递到新页面而无需程序员的直接操作。

例如:

  1. 我们进入页面myPage1.aspx?param1=test
  2. 执行 Response.Redirect(myPage2.aspx)
  3. 在这里我希望将参数连接到 URL 和结果:
  4. 页面被重定向到 myPage2.aspx?param1=test

解决方案应该知道用户可以打开多个共享一个会话(身份验证)的应用程序实例。例如,在一个浏览器中打开 myPage.aspx?param1=test,在第二个浏览器中打开 mypage.aspx?param1=test2。

我们已经在应用程序中进行了一些重定向 (Response.Redirect),因此完美的解决方案不需要更改现有代码。

可以吗?

【问题讨论】:

    标签: c# asp.net


    【解决方案1】:

    如果您不想使用 Session 并且只想使用查询字符串参数,可以使用以下操作

    1. 您可以像这样遍历所有查询字符串参数

    int循环1,循环2;

    // 加载 NameValueCollection 对象。

    NameValueCollection coll = Request.QueryString;

    // 将所有键的名称放入字符串数组中。 String[] arr1 = coll.AllKeys;

    字符串参数 = "";

    for (loop1 = 0; loop1

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

    for (loop2 = 0; loop2

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

    } }

    这只是基本的想法。但是您可以在不知道名称的情况下循环遍历参数。

    为了避免在每个页面上编写代码,您可以定义一个类,如

    公共类 QueryStringHelper { 公共静态字符串 GetQueryString(KeyValuePair 查询字符串) { //获取您的字符串并使用上述方法返回您的查询字符串 } }

    然后在每个页面上你必须在页面 PREINTI 事件中做

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

    我认为在每一页上复制这一事件不会是一个大问题。

    再一次,这段代码是基本的想法,这不会编译

    【讨论】:

    • 是的,但是是否有放置代码的地方以避免重写使用重定向的旧代码?
    • 只有当您不想加载页面并立即重定向时,您才可以使用页面的 PreInit 或 Init 事件来设置参数。但是,如果您想在重定向之前做某事,请先执行此操作,然后再重定向页面。最好的方法是您定义一个单独的类来获取参数并使用静态方法(公共静态字符串 getquerystringparameters())并传递查询字符串对象并获取参数字符串(“para1 = value1&para2 = value2”)作为回报只是为了附加到您的重定向页面。
    • 它仍然需要在每个页面或其父类上添加此代码。我想避免这种情况。
    • 我已经编辑了基本代码,请看代码。如果你想从每个页面重定向,不幸的是你必须在每个页面上都这样做,除非你 1. 让你自己的页面类继承自 Page 类并制作基本的预初始化页面并从你自己的页面类继承所有重定向页面,它将自动重定向从您自己的类继承的所有页面
    【解决方案2】:

    您可以使用Session 对象来执行此操作,而不是在 QueryString 上复制参数:

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

    另一种选择是使用cookies,以类似的方式:

    // in myPage1.aspx
    Response.Cookies["url"] = "a url";
    
    // in myPage2.aspx
    var passedInUrl = Request.Cookies["url"]
    

    这两种方式都适用于少量数据,但如果您想避免篡改(或能够发现篡改),您可能应该加密 cookie。

    【讨论】:

    • 好的。但是有没有没有会话的方法?对程序员透明?我们已经在应用程序中进行了一些重定向,我希望它们保持不变。
    • @rkrass - 您可以使用 cookie。为什么要避免会话?如果您希望在页面请求之间保留少量数据,那就太好了。
    • @Oded - 我们希望允许其他 Web 应用程序将参数传递给我们的应用程序。如果参数被传递,我不想松开它。在一个会话中,用户可以打开多个浏览器窗口,所以我认为不能使用会话参数。
    • @rkrass - 您可以在会话中存储数组和列表。检查会话对象是否为空,如果不是,则提取列表添加到它并重新分配给会话对象。
    • @Oded - 如果用户打开 2 个具有 2 个不同参数的浏览器窗口怎么办?第二个窗口将使用会话中的参数,因为它已经设置(共享会话)。这不是我需要的行为。
    【解决方案3】:

    您可以在每个页面的顶部实例化一个类来为您处理这个问题。我在下面写了一个例子。 ++注意这是未经测试的,我只是把它放在一起给你一个想法++:

    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()));
        }
    };
    

    让这个类成为你页面的成员:

    private QueryStringState m_QueryStringState = null;
    

    并在初始化期间实例化,通过页面传递您希望在查询字符串中保留的任何参数的名称:

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

    那么你必须确保任何离开页面的 URL 都通过这个类的 ResolveUrl() 方法传递:

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

    正如我所说,这是未经测试的,因为我现在没有时间确保它完全按预期工作,但只是让您大致了解如何解决这个问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-02-20
      • 1970-01-01
      • 2012-09-08
      • 1970-01-01
      • 2012-06-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多