TGStat
TGStat
Type to search
Advanced channel search
  • flag English
    Site language
    flag Russian flag English flag Uzbek
  • Sign In
  • Catalog
    Channels and groups catalog Regional compilations Thematic compilations Платные каналы Search for channels
    Add a channel/group
  • Ratings
    Rating of channels Rating of groups Posts rating
    Ratings of brands and people
  • Analytics
  • Search by posts
  • Telegram monitoring
  • Promotion
    Advertising through Yandex Business Advertising in channels through TGStat Agency Advertising on TGStat.ru website
.NET sh blog

22 Sep 2025, 20:47

Open in Telegram Share Report

Недавно на youtube появилась запись доклада "10 Things I Do On Every .NET App - Scott Sauber"

Добавлю свои 5 копеек

1. BootstrapLogger pattern
public static async Task Main(string[] args)
{
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
.Enrich.FromLogContext()
.WriteTo.Console(new JsonFormatter())
.CreateBootstrapLogger();

try
{
Log.Information("Starting BookLibrary");

var host = CreateHostBuilder(args).Build();

await host.MigrateAsync();

await host.RunAsync();
}
catch (Exception ex)
{
Log.Fatal(ex, "BookLibrary terminated unexpectedly");
}
finally
{
await Log.CloseAndFlushAsync();
}
}
Позволяет отправить в логи отладочную информацию о падении сервиса или ошибке её запуска.
Без обработчика ошибки такая информация чаще всего теряется.

2. Глобальный таймаут на Regex

На одном проекте много времени убили на поиск причины почему сервис вдруг перестает потреблять сообщения из шины и ребут не помогает.
После полного воспроизведения ситуации локально на продовых данных удалось выяснить, что Regex.IsMatch вызывался без заданного таймаута
и иногда попадался такой текст из-за которого сервис зависал намертво.
Было неприятно, но это легко пофиксилось переписыванием регулярки с обработкой возможного таймаута и добавлением глобального таймаута для защиты от такой ситуации.
С тех пор стараюсь в Program.cs везде добавлять настройку:
AppDomain.CurrentDomain.SetData("REGEX_DEFAULT_MATCH_TIMEOUT", TimeSpan.FromSeconds(1));

3. Ограничение размера тела HTTP запроса в Kestrel
builder.Services.Configure(options =>
{
options.Limits.MaxRequestBodySize = 20 * 1024; // 20 кб при превышении вернет 413 Payload Too Large
});

По-умолчанию лимит стоит 28.6 мегабайт, что очень много.
Если мы знаем что наш API не будет или не должен принимать большой объём данных, то можно снизить это дефолтное значение для уменьшения возможных атак на сервис.
Для отдельных запросов типа загрузки файлов этот лимит можно точечно настроить атрибутом [RequestSizeLimit]

Обычно такие лимиты могут настраиваться на стороне reverse proxy, но приложение всегда лучше знает о своих потребностях и ограничениях
и нужно помнить, что далеко не всегда приложение будет хоститься именно за этим reverse proxy.

4. Глобальный таймаут на запросы
services.AddRequestTimeouts(o => o.DefaultPolicy = new RequestTimeoutPolicy
{
Timeout = TimeSpan.FromSeconds(30)
});

app.UseRequestTimeouts();

По-умолчанию никакого таймаута нет. Таймауты обычно проставляются по-умолчанию на reverse proxy, но лучше это сделать и в приложении.

Добавление этих трех строк выше не гарантирует что запросы начнут отменяться. Оно лишь будет инициировать отмену запроса не дожидаясь когда отменит запрос клиент (если вообще отменит).
Для того чтобы запросы отменялись и расходовали лишние ресурсы нужно использовать CancellationToken.

5. Сокрытие деталей исключений JSON сериализатора (и не только)

По-умолчанию, если в API передать кривой JSON (например null, там где ожидается Guid), то AspNetCore выдаст отладочную информацию,
раскрывая внутренние типы и детали работы сериализатора. Также могут протечь какие-нибудь более чувствительные стектрейсы, что откроет еще больше зоны для атаки.

{
"type": "https://httpstatuses.io/400",
"title": "Некорректные параметры запроса",
"status": 400,
"errors": {
"$.id": [
"The JSON value could not be converted to System.Guid. Path: $.id | LineNumber: 2 | BytePositionInLine: 8."
]
}
}

Для прода рекомендуется отключить:
services
.AddControllers()
.AddJsonOptions(o => o.AllowInputFormatterExceptionMessages = false);

Тогда ошибка уже в будет в таком виде
{
"type": "https://httpstatuses.io/400",
"title": "Некорректные параметры запроса",
"status": 400,
"errors": {
"$.id": [
"The input was not valid."
]
}
}

603 0 22 1 31
Catalog
Channels and groups catalog Channels compilations Search for channels Add a channel/group
Ratings
Rating of Telegram channels Rating of Telegram groups Posts rating Ratings of brands and people
API
API statistics Search API of posts API Callback
Our channels
@TGStat @TGStat_Chat @telepulse @TGStatAPI
Read
Академия TGStat Telegram Research 2019 Telegram Research 2021 Telegram Research 2023
Contacts
Справочный центр Support Email Jobs
Miscellaneous
Terms and conditions Privacy policy Public offer
Our bots
@TGStat_Bot @SearcheeBot @TGAlertsBot @tg_analytics_bot @TGStatChatBot