【问题标题】:How to combine URLs with query string parts preserved?如何将 URL 与保留的查询字符串部分结合起来?
【发布时间】:2012-10-13 15:05:05
【问题描述】:

我正在编写一个需要调用 web 应用程序的 C# 应用程序。我正在尝试使用System.Uri 组合两个 URL:一个基本 URL 和我需要的 webapp 的特定服务(或许多)的相对路径。我有一个名为 webappBackendURL 的类成员,我想在一个地方定义它,所有调用都是从它构建的(webappBackendURL 的定义并不像我的示例所示那样接近)。

System.Uri webappBackendURL = new System.Uri("http://example.com/");
System.Uri rpcURL           = new System.Uri(webappBackendURL,"rpc/import");
// Result: http://example.com/rpc/import

但是,如果webappBackendURL 包含查询字符串,则它不会被保留。

System.Uri webappBackendURL = new System.Uri("http://example.com/?authtoken=0x0x0");
System.Uri rpcURL           = new System.Uri(webappBackendURL,"rpc/import");
// Result: http://example.com/rpc/import <-- (query string lost)

有没有更好的方法来组合 URL? .NET 库非常广泛,所以我想我可能只是忽略了一种处理此问题的内置方法。理想情况下,我希望能够像这样组合 URL:

System.Uri webappBackendURL = new System.Uri("http://example.com/?authtoken=0x0x0");
System.Uri rpcURL           = new System.Uri(webappBackendURL,"rpc/import?method=overwrite&runhooks=true");
// Result: http://example.com/rpc/import?authtoken=0x0x0&method=overwrite&runhooks=true

【问题讨论】:

    标签: c# url


    【解决方案1】:

    你可以这样做:

    System.Uri webappBackendURL = 
      new System.Uri("http://example.com/?authtoken=0x0x0");
    System.Uri rpcURL = new System.Uri(webappBackendURL,
      "rpc/import?ethod=overwrite&runhooks=true" 
      + webappBackendURL.Query.Replace("?", "&"));
    

    【讨论】:

      【解决方案2】:
      System.Uri webappBackendURL = new System.Uri("http://example.com/?authtoken=0x0x0");
      System.Uri rpcURL           = new System.Uri(webappBackendURL,string.Format("rpc/import?{0}method=overwrite&runhooks=true", string.IsNullOrWhiteSpace(webappBackendURL.Query) ? "":webappBackendURL.Query + "&"));
      

      虽然我可能会创建一个采用两个 URI 并在那里进行处理的方法,以使其看起来更简洁。

      public static Uri MergerUri(Uri uri1, Uri uri2)
          {
              if (!string.IsNullOrWhiteSpace(uri1.Query))
              {
                  string[] split = uri2.ToString().Split('?');
      
                  return new Uri(uri1, split[0] + uri1.Query + "&" + split[1]);
              }
              else return new Uri(uri1, uri2.ToString());
          }
      

      【讨论】:

      • 当我尝试从我的简单路径构造Uri 时,我遇到了UriFormatException,所以我认为我不能可靠地使用MergerUri。我可能会尝试将您最初的建议包装成一个方法。
      • 对不起,我没有先测试它。更新后的会起作用,但它与您决定的相似。
      【解决方案3】:

      试试UriTemplate:

      Uri baseUrl = new Uri("http://www.example.com");
      UriTemplate template = new UriTemplate("/{path}/?authtoken=0x0x0");
      Uri boundUri = template.BindByName(
          baseUrl,
          new NameValueCollection {{"path", "rpc/import"}});
      

      System.UriTemplate 已在不同版本的 .NET 之间移动。您需要确定哪个程序集引用对您的项目是正确的。

      【讨论】:

      • 我只使用了一个参数,因为它最符合您的要求,但您可以拥有多个模板 (/{x}/{y}/foo)。显然,对于每个占位符,NameValueCollection 中都会有一个条目。
      【解决方案4】:

      使用收到的答案中的想法和片段,我编写了一个包装器方法,它完全实现了我正在寻找的东西。我希望核心 .NET 类可以处理这个问题,但看起来他们不能。

      此方法将采用完整的 URL (http://example.com?path?query=string) 并将 relative/path?query=string&amp;with=arguemnts 形式的相对 URL(字符串)组合到其中。

      private static System.Uri ExtendURL(System.Uri baseURL, string relURL)
      {
          string[] parts = relURL.Split("?".ToCharArray(), 2);
          if (parts.Length < 1)
          {
              return null;
          }
          else if (parts.Length == 1)
          {
              // No query string included with the relative URL:
              return new System.Uri(baseURL,
                                    parts[0] + baseURL.Query);
          }
          else
          {
              // Query string included with the relative URL:
              return new System.Uri(baseURL,
                                    parts[0] + (String.IsNullOrWhiteSpace(baseURL.Query) ? "?" : baseURL.Query + "&") + parts[1]);
          }
      }
      
      ExtendURL(new System.Uri("http://example.com/?authtoken=0x0x0"),"rpc/import?method=overwrite&runhooks=true");
      // Result: http://example.com/rpc/import?authtoken=0x0x0&method=overwrite&runhooks=true
      

      感谢所有做出贡献的人!我赞成你所有的答案。

      【讨论】:

        【解决方案5】:
        var originalUri = new Uri("http://example.com?param1=1&param2=2");
        var resultUri = new Uri(new Uri(originalUri, "/something"), originalUri.Query);
        

        resultUri:http://example.com/something?param1=1&param2=2

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-07-26
          • 2018-09-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多