Кодирование пробелов в URL на C#: от String.Replace до Uri.EscapeDataString

Разбираемся, как правильно заменять пробелы на %20 в C#. Избегайте ошибок при формировании ссылок для онлайн-консультаций и веб-запросов.

При формировании URL‑адресов для онлайн‑консультаций часто возникает необходимость корректно кодировать
строки, содержащие пробелы. В веб‑протоколе пробелы заменяются на %20 (или на знак «+», если используется
application/x-www-form-urlencoded). В этой статье мы подробно разберём, как правильно выполнить замену
пробелов в C# и какие подводные камни могут встретиться.

Содержание

  1. Зачем кодировать пробелы?
  2. Наивный способ: String.Replace
  3. Стандартные методы .NET: Uri.EscapeDataString и HttpUtility.UrlEncode
  4. Кастомный заменитель с учётом Unicode
  5. Интеграция в ASP.NET MVC / Razor Pages
  6. Юнит‑тесты для проверки корректности
  7. Типичные ошибки и как их избежать

Почему важно заменять пробелы на %20?

URL (Uniform Resource Locator) – это строка, передаваемая в HTTP‑запросе; Согласно RFC 3986,
пробелы в URL недопустимы и должны быть заменены на их percent‑encoding – %20. Если этого не сделать,
браузер может:

  • Отказаться от перехода по ссылке;
  • Неправильно интерпретировать часть URL как отдельный параметр;
  • Вызвать ошибку 400 Bad Request на стороне сервера.

Для онлайн‑консультаций гадалок часто формируються ссылки вида:

https://example.com/consultation?topic=Любовный совет

Без кодирования пробел в параметре topic запрос будет некорректным.

Наивный способ: String.Replace

Самый простой способ – заменить каждый пробел символом %20:

string raw = "Любовный совет онлайн";
string encoded = raw.Replace(" ", "%20");
Console.WriteLine(encoded); // Любовный%20совет%20онлайн

Этот метод работает, если в строке только ASCII‑пробелы и нет других символов, требующих кодирования (например,
русских букв, знаков пунктуации, символов «&», «?», «#» и т.д.). В реальном проекте такой подход часто приводит к багам.

Стандартные методы .NET

3.1 Uri.EscapeDataString

Метод полностью кодирует строку, заменяя все символы, которые не являются «неразрешёнными» в URI‑части.

string raw = "Любовный совет онлайн";
string encoded = Uri.EscapeDataString(raw);
Console.WriteLine(encoded); // %D0%9B%D1%8E%D0%B1%D0%BE%D0%B2%D0%BD%D1%8B%D0%B9%20%D1%81%D0%BE%D0%B2%D0%B5%D1%82%20%D0%BE%D0%BD%D0%BB%D0%B0%D0%B9%D0%BD

Обратите внимание: русские буквы кодируются в UTF‑8, а пробел – в %20. Это именно то, что требуется для
корректных URL.

3.2 HttpUtility.UrlEncode (System.Web)

Если ваш проект использует System.Web, можно воспользоваться:

using System.Web;

string raw = "Любовный совет онлайн";
string encoded = HttpUtility.UrlEncode(raw);
Console.WriteLine(encoded); // %D0%9B%D1%8E%D0%B1%D0%BE%D0%B2%D0%BD%D1%8B%D0%B9+%D1%81%D0%BE%D0%B2%D0%B5%D1%82+%D0%BE%D0%BD%D0%BB%D0%B0%D0%B9%D0%BD

Здесь пробел заменяется на «+», что соответствует application/x-www-form-urlencoded. Если нужен именно %20,
замените «+» обратно:

string encoded = HttpUtility.UrlEncode(raw).Replace("+", "%20");

3.3 WebUtility.UrlEncode (System.Net)

Для .NET Core и .NET 5/6/7 рекомендуется использовать System.Net.WebUtility:

using System.Net;

string raw = "Любовный совет онлайн";
string encoded = WebUtility.UrlEncode(raw);
Console.WriteLine(encoded); // %D0%9B%D1%8E%D0%B1%D0%BE%D0%B2%D0%BD%D1%8B%D0%B9+%D1%81%D0%BE%D0%B2%D0%B5%D1%82+%D0%BE%D0%BD%D0%BB%D0%B0%D0%B9%D0%BD

Поведение аналогично HttpUtility.UrlEncode – пробелы заменяются на «+». При необходимости замените их на %20.

Кастомный заменитель с учётом Unicode

Если по какой‑то причине вы хотите полностью контролировать процесс кодирования, можно написать небольшую функцию.
Ниже пример, который заменяет только пробелы, а остальные символы оставляет без изменений (полезно, если уже
используется Uri.EscapeDataString для остальных символов):

/// <summary>

/// Кодирует строку, заменяя пробелы на %20 и оставляя остальные символы без изменений.
/// </summary>
public static string EncodeSpacesOnly(string input)
{
 if (string.IsNullOrEmpty(input))
 return input;

 // StringBuilder более эффективен, чем многократные конкатенации.
 var sb = new System.Text.StringBuilder(input.Length * 3);
 foreach (char c in input)
 {
 if (c == ' ')
 sb.Append("%20");
 else
 sb.Append(c);
 }
 return sb.ToString;
}
// Пример использования
string raw = "Любовный совет онлайн";
string partiallyEncoded = Uri.EscapeDataString(raw); // кодируем всё
string finalUrl = EncodeSpacesOnly(partiallyEncoded);
Console.WriteLine(finalUrl);
// %D0%9B%D1%8E%D0%B1%D0%BE%D0%B2%D0%BD%D1%8B%D0%B9%20%D1%81%D0%BE%D0%B2%D0%B5%D1%82%20%D0%BE%D0%BD%D0%BB%D0%B0%D0%B9%D0%BD

В данном примере Uri.EscapeDataString уже заменил пробел на %20, но если вы используете другой
метод, EncodeSpacesOnly гарантирует, что ни один пробел не останется «сырым».

Интеграция в ASP.NET MVC / Razor Pages

Часто ссылки генерируются в представлениях. Ниже показано, как правильно формировать URL в Razor:

@{
 string topic = "Любовный совет онлайн";
 // Используем Uri.EscapeDataString для безопасного кодирования
 string encodedTopic = Uri.EscapeDataString(topic);
 string url = $"https://example.com/consultation?topic={encodedTopic}";
}<a href="@url">Записаться на консультацию</a>

Если вы используете TagHelper asp-route-*, кодирование происходит автоматически:

<a asp-controller="Consultation"
 asp-action="Index"
 asp-route-topic="@topic">Записаться</a>

ASP.NET Core сам выполнит UrlEncoder и заменит пробелы на %20.

Юнит‑тесты для проверки корректности

Рекомендуется покрыть код тестами, чтобы гарантировать отсутствие регрессий.

using NUnit.Framework;
using System;

[TestFixture]
public class UrlEncodingTests
{
 [TestCase("Любовный совет онлайн", "%D0%9B%D1%8E%D0%B1%D0%BE%D0%B2%D0%BD%D1%8B%D0%B9%20%D1%81%D0%BE%D0%B2%D0%B5%D1%82%20%D0%BE%D0%BD%D0%BB%D0%B0%D0%B9%D0%BD")]
 [TestCase("Hello World", "Hello%20World")]
 public void EscapeDataString_ShouldEncodeSpacesAsPercent20(string input, string expected)
 {
 string actual = Uri.EscapeDataString(input);
 Assert.AreEqual(expected, actual);
 }

 [TestCase("Hello World", "Hello%20World")]
 public void ReplaceSpacesOnly_ShouldWork(string input, string expected)
 {
 string encoded = Uri.EscapeDataString(input);
 string final = EncodeSpacesOnly(encoded);
 Assert.AreEqual(expected, final);
 }
}

Типичные ошибки и как их избежать

  • Забыть про UTF‑8. Простая Replace(" ", "%20") не кодирует нелатинские символы, что приводит к невалидным URL.
  • Двойное кодирование. Если вызвать Uri.EscapeDataString дважды, уже закодированные последовательности
    (%20) превратятся в %2520. Проверяйте, не вызываете ли вы кодировщик несколько раз.
  • Использование + вместо %20. Для обычных GET‑запросов лучше использовать %20,
    иначе сервер может интерпретировать «+» как пробел только в контексте формы.
  • Неправильный набор символов. В старых версиях .NET HttpUtility.UrlEncode использует кодировку
    Windows‑1251 по умолчанию, что ломает русские символы. Указывайте явно Encoding.UTF8:
    HttpUtility.UrlEncode(raw, Encoding.UTF8)
  • Пропуск символов «/» и «?». Если вы кодируете часть пути, а не параметр запроса, используйте
    Uri.EscapeUriString вместо EscapeDataString, иначе «/» будет заменён на %2F,
    что изменит структуру пути.

Для генерации корректных ссылок на онлайн‑консультации гадалок в C# необходимо заменять пробелы на %20.
Самый надёжный способ – использовать встроенные методы .NET, такие как Uri.EscapeDataString или
WebUtility.UrlEncode, а при необходимости выполнить пост‑обработку (например, заменить «+» на %20).
Ниже подытожим основные рекомендации:

  • Не используйте простую Replace, если в строке могут быть нелатинские символы.
  • Выбирайте метод кодирования в зависимости от контекста: EscapeDataString для параметров запроса,
    EscapeUriString для частей пути.
  • Всегда проверяйте результат с помощью юнит‑тестов.
  • В ASP.NET Core полагайтесь на встроенные TagHelper и UrlEncoder – они делают всё автоматически.

Следуя этим рекомендациям, вы избежите проблем с некорректными URL и обеспечите надёжную работу вашего сервиса
по онлайн‑консультациям.


Статья написана 06:14:36.