【问题标题】:A clean way of generating QueryString parameters for web requests一种为 Web 请求生成 QueryString 参数的简洁方法
【发布时间】:2010-09-27 09:02:53
【问题描述】:

我在当前的应用程序中遇到了一个问题,需要摆弄 Page 基类(我的所有页面都继承自)中的查询字符串来解决问题。由于我的一些页面使用查询字符串,我想知道是否有任何类提供干净和简单的查询字符串操作。

代码示例:

// What happens if I want to future manipulate the query string elsewhere
// (e.g. maybe rewrite when the request comes back in)
// Or maybe the URL already has a query string (and the ? is invalid)

Response.Redirect(Request.Path + "?ProductID=" + productId);

【问题讨论】:

    标签: c# .net asp.net url


    【解决方案1】:

    按照某人的建议使用HttpUtility.ParseQueryString(然后删除)。

    这将起作用,因为该方法的返回值实际上是一个HttpValueCollection,它继承了NameValueCollection(并且是内部的,您不能直接引用它)。然后,您可以正常设置集合中的名称/值(包括添加/删除),并调用 ToString -- 这将生成完成的查询字符串,因为 HttpValueCollection 覆盖 ToString 以重现实际的查询字符串。

    【讨论】:

    • ParseQueryString 将只采用 URL 的查询字符串部分(而不是路径),并且不会在其前面加上问号。
    • 然后呢?从 URL 中提取查询字符串很简单(例如,使用 System.Uri 类,或简单的 string.Split 或 string.Substring),一旦你拥有它,你就知道它不能在内部包含问号(它们会被编码),所以只需执行 url + "?" + queryString.ToString().
    【解决方案2】:

    我希望找到一个内置到框架中的解决方案,但没有。 (框架中的那些方法需要做很多工作才能使其简单明了)

    在尝试了几种替代方案后,我目前使用以下扩展方法:(发布更好的解决方案或发表评论)

    public static class UriExtensions
    {
        public static Uri AddQuery(this Uri uri, string name, string value)
        {
            string newUrl = uri.OriginalString;
    
            if (newUrl.EndsWith("&") || newUrl.EndsWith("?"))
                newUrl = string.Format("{0}{1}={2}", newUrl, name, value);
            else if (newUrl.Contains("?"))
                newUrl = string.Format("{0}&{1}={2}", newUrl, name, value);
            else
                newUrl = string.Format("{0}?{1}={2}", newUrl, name, value);
    
            return new Uri(newUrl);
        }
    }
    

    这种扩展方法可以实现非常干净的重定向和 uri 操作:

    Response.Redirect(Request.Url.AddQuery("ProductID", productId).ToString());
    
    // Will generate a URL of www.google.com/search?q=asp.net
    var url = new Uri("www.google.com/search").AddQuery("q", "asp.net")
    

    适用于以下网址:

    "http://www.google.com/somepage"
    "http://www.google.com/somepage?"
    "http://www.google.com/somepage?OldQuery=Data"
    "http://www.google.com/somepage?OldQuery=Data&"
    

    【讨论】:

    • 如果名称或值中包含非法字符(例如?或 &)会怎样?并且使用 System.Uri 但自己进行解析而不是使用 Query 属性是毫无意义的。
    【解决方案3】:

    请注意,无论您使用何种路由,您都应该真正对值进行编码 - Uri.EscapeDataString 应该为您做到这一点:

    string s = string.Format("http://somesite?foo={0}&bar={1}",
                Uri.EscapeDataString("&hehe"),
                Uri.EscapeDataString("#mwaha"));
    

    【讨论】:

    • 是的,因为您在 asp.net 中,这也可以完成这项工作。从更一般的意义上说,您可能没有(或在某些情况下无法拥有,如 Silverlight / CF / 客户端配置文件)对 System.Web.dll 的引用 - 但在这种情况下很好。
    【解决方案4】:

    我通常做的只是重建查询字符串。 Request 有一个 QueryString 集合。

    您可以对其进行迭代以获取当前(未编码)参数,然后使用适当的分隔符将它们连接在一起(随时编码)。

    优点是 Asp.Net 已经为你做了原始解析,所以你不用担心尾随 & 和 ?s 等边缘情况。

    【讨论】:

      【解决方案5】:

      检查一下!!!

      // First Get The Method Used by Request i.e Get/POST from current Context
      string method = context.Request.HttpMethod;
      
      // Declare a NameValueCollection Pair to store QueryString parameters from Web Request
      NameValueCollection queryStringNameValCollection = new NameValueCollection();
      
      if (method.ToLower().Equals("post")) // Web Request Method is Post
      {
         string contenttype = context.Request.ContentType;
      
         if (contenttype.ToLower().Equals("application/x-www-form-urlencoded"))
         {
            int data = context.Request.ContentLength;
            byte[] bytData = context.Request.BinaryRead(context.Request.ContentLength);
            queryStringNameValCollection = context.Request.Params;
         }
      }
      else // Web Request Method is Get
      {
         queryStringNameValCollection = context.Request.QueryString;
      }
      
      // Now Finally if you want all the KEYS from QueryString in ArrayList
      ArrayList arrListKeys = new ArrayList();
      
      for (int index = 0; index < queryStringNameValCollection.Count; index++)
      {
         string key = queryStringNameValCollection.GetKey(index);
         if (!string.IsNullOrEmpty(key))
         {
            arrListKeys.Add(key.ToLower());
         }
      }
      

      【讨论】:

        【解决方案6】:

        我找到了使用 get 参数轻松操作的方法。

        public static string UrlFormatParams(this string url, string paramsPattern, params object[] paramsValues)
        {
            string[] s = url.Split(new string[] {"?"}, StringSplitOptions.RemoveEmptyEntries);
            string newQueryString = String.Format(paramsPattern, paramsValues);
            List<string> pairs = new List<string>();
        
            NameValueCollection urlQueryCol = null;
            NameValueCollection newQueryCol = HttpUtility.ParseQueryString(newQueryString);
        
            if (1 == s.Length)
            {
                urlQueryCol = new NameValueCollection();
            }
            else
            {
                urlQueryCol = HttpUtility.ParseQueryString(s[1]);
            }
        
        
        
            for (int i = 0; i < newQueryCol.Count; i++)
            {
                string key = newQueryCol.AllKeys[i];
                urlQueryCol[key] = newQueryCol[key];
            }
        
            for (int i = 0; i < urlQueryCol.Count; i++)
            {
                string key = urlQueryCol.AllKeys[i];
                string pair = String.Format("{0}={1}", key, urlQueryCol[key]);
                pairs.Add(pair);
            }
        
            newQueryString = String.Join("&", pairs.ToArray());
        
            return String.Format("{0}?{1}", s[0], newQueryString);
        }
        

        像这样使用它

        "~/SearchInHistory.aspx".UrlFormatParams("t={0}&s={1}", searchType, searchString)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-10
          • 1970-01-01
          • 2021-11-06
          相关资源
          最近更新 更多