Отключить URL-кодировку знака равенства в значении параметра - PullRequest
0 голосов
/ 07 февраля 2019

У меня есть этот код ниже, который создает коллекцию параметров запроса для спокойного вызова веб-службы

NameValueCollection outgoingQueryString = HttpUtility.ParseQueryString(String.Empty);
outgoingQueryString.Add("SessionID", _sessionId);
outgoingQueryString.Add("LoanNumberID", loanId.ToString());
outgoingQueryString.Add("Nonce", _nonce);
outgoingQueryString.Add("OtherParams", "Enable_Filter_Show_on_Action_Report=0");

Проблема состоит в том, что последнее значение параметра Enable_Filter_Show_on_Action_Report = 0 получает его '=', закодированный в% 3d SessionID=319A561B6D&LoanNumberID=351591&Nonce=3262383361&OtherParams=Enable_Filter_Show_on_Action_Report%3d0

когда должно быть

SessionID=319A561B6D&LoanNumberID=351591&Nonce=3262383361&OtherParams=Enable_Filter_Show_on_Action_Report=0

, если не делать переписывания после того, как есть какой-то способ предотвратить это?Служба не возвращает правильный набор результатов, потому что она интерпретирует% 3d как нечто, что необходимо отфильтровать.

Что я сделал, чтобы исправить проблему, было следующим.Я просто не знал, есть ли способ предотвратить это.

string queryString = outgoingQueryString.ToString().Replace("%3d", "=");

1 Ответ

0 голосов
/ 07 февраля 2019

Я не знаю, как заставить NameValueCollection делать то, что вы хотите;вы, вероятно, застряли с каким-то обходным решением.

Я вижу потенциальную проблему в вашей реализации обходного пути:

[Fact]
public void ProblemWithOriginalSolution()
{
    NameValueCollection outgoingQueryString = HttpUtility.ParseQueryString(String.Empty);
    outgoingQueryString.Add("Param1", "Value1");
    outgoingQueryString.Add("Param2", "Value2=Something"); // this '=' needs to remain URL-encoded
    outgoingQueryString.Add("OtherParams", "Enable_Filter_Show_on_Action_Report=0");

    var queryString = outgoingQueryString.ToString().Replace("%3d", "=");

    Assert.Contains("Value2=Something", queryString); // Passes, but not what we want
    Assert.Contains("Value2%3dSomething", queryString); // Actually what we want, but fails
}

Это может не иметь значения для ваших нужд, но если это такУ меня есть два предложения.

Первое - просто использовать конкатенацию строк.В зависимости от вашего использования может потребоваться дополнительная логика для обработки случая, когда OtherParams является единственным параметром строки запроса (амперсанд в этом случае должен быть опущен).Конкатенация строк также является плохой идеей: OtherParams может содержать символы, которые должны быть закодированы в URL.

[Fact]
public void Concatentation()
{
    NameValueCollection outgoingQueryString = HttpUtility.ParseQueryString(String.Empty);
    outgoingQueryString.Add("Param1", "Value1");

    var queryString = outgoingQueryString.ToString() + "&OtherParams=Enable_Filter_Show_on_Action_Report=0";

    Assert.Contains("&OtherParams=Enable_Filter_Show_on_Action_Report=0", queryString);
}

Второе - сделать двойную подстановку.Это немного жестко, и не очень эффективно, но должно быть надежно.

[Fact]
public void DoubleSubstitution()
{
    // Make sure the placeholder doesn't have any characters that will get URL encoded!
    // Also make sure it's not something that could appear in your input.
    const string equalsPlaceholder = "__Equals__";

    NameValueCollection outgoingQueryString = HttpUtility.ParseQueryString(String.Empty);
    outgoingQueryString.Add("Param1", "Value1");

    // First, remove the equals signs from the OtherParams value
    outgoingQueryString.Add("OtherParams", "Enable_Filter_Show_on_Action_Report=0".Replace("=", equalsPlaceholder));

    // Then, build the query string, and substitute the equals signs back in
    var queryString = outgoingQueryString.ToString().Replace(equalsPlaceholder, "=");

    Assert.Contains("&OtherParams=Enable_Filter_Show_on_Action_Report=0", queryString);
}
...