【问题标题】:Is there a simple way to get query string parameters from a URI in Windows Phone?有没有一种简单的方法可以从 Windows Phone 中的 URI 获取查询字符串参数?
【发布时间】:2013-04-08 21:00:08
【问题描述】:

我目前正在使用自定义 URI 方案来验证使用 OAuth 的用户。为此,我需要从查询字符串中获取某些参数的值。

有没有简单的方法来获取这些信息?还是我唯一的选择是使用 REGEX 或其他字符串操作?

我之前发现过对 ParseQueryString 之类的引用,但它们包含在 Windows Phone 上不可用的库中。

【问题讨论】:

标签: c# windows-phone-8 uri query-string windows-phone


【解决方案1】:

经过大量搜索后,我找到了一种简单的方法。只要查询字符串保持相当简单(就像它们在 OAuth 中一样),这个方法应该可以工作。

public static Dictionary<string, string> ParseQueryString( string uri ) {

    string substring = uri.Substring( ( ( uri.LastIndexOf('?') == -1 ) ? 0 : uri.LastIndexOf('?') + 1 ) );

    string[] pairs = substring.Split( '&' );

    Dictionary<string,string> output = new Dictionary<string,string>();

    foreach( string piece in pairs ){
        string[] pair = piece.Split( '=' );
        output.Add( pair[0], pair[1] );
    }

    return output;

}

【讨论】:

    【解决方案2】:

    来自https://stackoverflow.com/a/25164964/1033581

    • 在 Uri 中处理 #
    • 处理可能的缺失值,例如 Uri 中的 &name=
    • 不要忘记Uri.UnescapeDataString
    • 返回 Dictionary 而不是 IEnumerable,以便轻松找到所需的参数

    对于 Windows Phone 7 设备(或者您只有一个字符串,而不是 Uri,那么只需将 uri.OriginalString 替换为您的字符串),

    static readonly char[] QueryStringSeparator1 = "#".ToCharArray();
    static readonly char[] QueryStringSeparator2 = "?".ToCharArray();
    static readonly char[] QueryStringSeparator3 = "&".ToCharArray();
    static readonly char[] QueryStringSeparator4 = "=".ToCharArray();
    public static Dictionary<string, string> QueryDictionary(this Uri uri)
    {
        return uri.OriginalString
            .Split(QueryStringSeparator1, StringSplitOptions.RemoveEmptyEntries)
            .Select(a => a.Split(QueryStringSeparator2, StringSplitOptions.RemoveEmptyEntries)
                .Select(b => b.Split(QueryStringSeparator3, StringSplitOptions.RemoveEmptyEntries)
                    .Select(c => c.Split(QueryStringSeparator4))
                    .Where(c => c[0].Length > 0)
                    .ToDictionary(c => Uri.UnescapeDataString(c[0]), c => c.Length > 1 ? Uri.UnescapeDataString(c[1]) : ""))
                .ElementAtOrDefault(1))// after ?
            .FirstOrDefault()// before #
            ?? new Dictionary<string, string>();
    }
    

    注意:在 Windows Phone 7 设备上,Uri.Query 对于像“mailto:a@example.com?subject=subject&body=body”这样的 Uri 是不可靠的。这就是我们使用Uri.OriginalString 的原因。

    对于 Windows Phone 8 设备并且你有一个 Uri,你可以这样优化,

    static readonly char[] QueryStringSeparator1 = "#".ToCharArray();
    static readonly char[] QueryStringSeparator3 = "&".ToCharArray();
    static readonly char[] QueryStringSeparator4 = "=".ToCharArray();
    public static Dictionary<string, string> QueryDictionary(this Uri uri)
    {
        return uri.Query
            .Split(QueryStringSeparator1, StringSplitOptions.RemoveEmptyEntries)
            .Select(a => a.Substring(1)
                .Split(QueryStringSeparator3, StringSplitOptions.RemoveEmptyEntries)
                .Select(c => c.Split(QueryStringSeparator4))
                .Where(c => c[0].Length > 0)
                .ToDictionary(c => Uri.UnescapeDataString(c[0]), c => c.Length > 1 ? Uri.UnescapeDataString(c[1]) : ""))
            .FirstOrDefault()// before #
            ?? new Dictionary<string, string>();
    }
    

    如果您想知道您是否在使用 Windows Phone 7 应用的 Windows Phone 8 设备上:

    public static readonly bool IsVersion8 = Environment.OSVersion.Version >= new Version(8, 0);
    

    【讨论】:

      【解决方案3】:

      在 Windows Phone XNA 游戏中,从您的 Game 类 ctor 中访问类似这样的启动参数:

      foreach (var lp in this.LaunchParameters) {
          Debug.WriteLine("  Key={0}, Value={1}", lp.Key, lp.Value);
      }
      

      在 Silverlight/XAML 应用程序中,您将使用来自 Application_Startup(object sender, StartupEventArgs e) 事件处理程序的 e.InitParams。如何做到这一点的一个例子在这里:

      http://weblogs.asp.net/lduveau/archive/2009/08/15/provide-startup-parameters-to-silverlight-with-initparams.aspx

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-05-31
        • 2017-03-13
        • 1970-01-01
        • 1970-01-01
        • 2017-07-05
        • 2011-03-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多