C# URL 编码 (net481)

问题描述 投票:0回答:1

我尝试为电影网站构建搜索查询,而我作为欧洲人,我们有一些奇怪的角色。

这是我的起始代码:

private static string GetSearchUrl(string name)
{
    var uriBuilder = new UriBuilder("https://www.themoviedb.org/search");
    var query = HttpUtility.ParseQueryString(uriBuilder.Query);
    query.Add("query", name);
    uriBuilder.Query = query.ToString();
    var searchUrl = uriBuilder.ToString();
    return searchUrl;
}

这些是我的测试用例:

const string Source = "Zur Hölle mit den Paukern";
const string Source = "Astérix & Obélix";

当我在

net6.0
中创建单元测试库时,一切都很好,结果是:

https://www.themoviedb.org:443/search?query=Zur+H%c3%b6lle+mit+den+Paukern
https://www.themoviedb.org:443/search?query=Ast%c3%a9rix+%26+Ob%c3%a9lix

但是,在我的目标框架中运行完全相同的功能

net481
我明白了

https://www.themoviedb.org:443/search?query=Zur+H%u00f6lle+mit+den+Paukern
https://www.themoviedb.org:443/search?query=Ast%u00e9rix+%26+Ob%u00e9lix

ö
字符在
%c3%b6
中编码为
net6.0
,但在
%u00f6
中编码为
net481
é
%c3%a9
中编码为
net6.0
,但在
%u00e9
中编码为
net481
。 这不能用作调用 URL(至少在 themoviedb.org 上不能)

我首先尝试将编码从 UTF-8 转换为 Windows-1252:

var win1252 = Encoding.GetEncoding(1252).GetString(Encoding.UTF8.GetBytes(name));
query.Add("query", win1252);

但这没有什么区别。

我也在不同的地方玩过

Uri.EscapeDataString()
,但这通常会让事情变得更糟。

net6.0
中,
query
后面的实际类型是

System.Collections.Specialized.NameValueCollection
{System.Web.HttpUtility.HttpQSCollection}

net481

System.Collections.Specialized.NameValueCollection
{System.Web.HttpValueCollection}

但这些是

HttpUtility.ParseQueryString()
调用返回的内部实现

c# url urlencode
1个回答
0
投票

Heretic Monkey 的帮助下,我决定编写自己版本的 QueryBuilder,它可以在

net6.0
net481
中实现我的目的:

public sealed class HttpGetQueryBuilder
{
    private readonly Dictionary<string, string> _queryParameters;

    public HttpGetQueryBuilder()
    {
        _queryParameters = new Dictionary<string, string>();
    }

    public HttpGetQueryBuilder(string query)
        : this()
    {
        var keyValues = HttpUtility.ParseQueryString(query);

        foreach (var key in keyValues.AllKeys)
        {
            this.Add(key, keyValues[key]);
        }
    }

    public string this[string key]
    {
        get => _queryParameters[key];
        set => _queryParameters[key] = value;
    }

    public void Add(string key, string value)
        => _queryParameters.Add(key, value);

    public override string ToString()
    {
        var queryBuilder = new StringBuilder();

        var keyIndex = 0;

        foreach (var keyValue in _queryParameters)
        {
            queryBuilder.Append($"{Uri.EscapeDataString(keyValue.Key)}={Uri.EscapeDataString(keyValue.Value)}");

            keyIndex++;

            if (keyIndex < _queryParameters.Count)
            {
                queryBuilder.Append('&');
            }
        }

        return queryBuilder.ToString();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.