При формировании URL‑адресов для онлайн‑консультаций часто возникает необходимость корректно кодировать
строки, содержащие пробелы. В веб‑протоколе пробелы заменяются на %20 (или на знак «+», если используется
application/x-www-form-urlencoded). В этой статье мы подробно разберём, как правильно выполнить замену
пробелов в C# и какие подводные камни могут встретиться.
Содержание
- Зачем кодировать пробелы?
- Наивный способ:
String.Replace - Стандартные методы .NET:
Uri.EscapeDataStringиHttpUtility.UrlEncode - Кастомный заменитель с учётом Unicode
- Интеграция в ASP.NET MVC / Razor Pages
- Юнит‑тесты для проверки корректности
- Типичные ошибки и как их избежать
Почему важно заменять пробелы на %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.