Свойства A и B эквивалентны?
public class MyClass
{ public int A { get; } = Random.Shared.Next(1000); public int B => Random.Shared.Next(1000); }
public class MyClass
{ public int A { get; } = Random.Shared.Next(1000); public int B => Random.Shared.Next(1000); }
Anonymous Quiz
25%
да
75%
нет
👍14
День 1668. #ЗаметкиНаПолях
Используем Секреты в Юнит-Тестах
Хотя большинство юнит-тестов должны соответствовать характеристикам FIRST и быть «изолированными» путём имитации их зависимостей, бывают случаи, когда может быть полезно фактически подключиться к внешнему ресурсу, и использовать средство запуска модульных тестов для проверки вашего кода на «реальной» зависимости. По сути, такие тесты являются интеграционными, но не будем сейчас углубляться в терминологию.
Допустим, вам нужна строка подключения к базе данных или другому внешнему ресурсу. Но вы не хотите включать её в код, поскольку все мы знаем, что секретам не место в системе контроля версий. Конечно, очевидным решением было бы получить доступ к строке подключения как к переменной среды, но Visual Studio Test Explorer (по крайней мере, насколько я могу судить) не предлагает простого способа установки переменных среды для запуска тестов. Существует файл .runsettings, но он страдает от точно такой же проблемы — в конечном итоге вам придётся добавить секреты в систему контроля версий.
К счастью, функция пользовательских секретов .NET может помочь нам в этом. И хотя во многих статьях о ней предполагается, что вы используете ASP.NET Core, вы можете использовать пользовательские секреты .NET в любом типе проекта, включая тестовую сборку.
Всё довольно просто. Сначала в командной строке в каталоге проекта модульного тестирования введите команду
Затем вы можете сохранить свой секрет с помощью команды user-secrets set, например:
Если вы запускаете тесты в конвейере CI/CD, можно использовать переменные среды машины, на которой запущен конвейер. Просто добавьте вызов
Источник: https://markheath.net/post/use-secrets-in-unit-tests
Используем Секреты в Юнит-Тестах
Хотя большинство юнит-тестов должны соответствовать характеристикам FIRST и быть «изолированными» путём имитации их зависимостей, бывают случаи, когда может быть полезно фактически подключиться к внешнему ресурсу, и использовать средство запуска модульных тестов для проверки вашего кода на «реальной» зависимости. По сути, такие тесты являются интеграционными, но не будем сейчас углубляться в терминологию.
Допустим, вам нужна строка подключения к базе данных или другому внешнему ресурсу. Но вы не хотите включать её в код, поскольку все мы знаем, что секретам не место в системе контроля версий. Конечно, очевидным решением было бы получить доступ к строке подключения как к переменной среды, но Visual Studio Test Explorer (по крайней мере, насколько я могу судить) не предлагает простого способа установки переменных среды для запуска тестов. Существует файл .runsettings, но он страдает от точно такой же проблемы — в конечном итоге вам придётся добавить секреты в систему контроля версий.
К счастью, функция пользовательских секретов .NET может помочь нам в этом. И хотя во многих статьях о ней предполагается, что вы используете ASP.NET Core, вы можете использовать пользовательские секреты .NET в любом типе проекта, включая тестовую сборку.
Всё довольно просто. Сначала в командной строке в каталоге проекта модульного тестирования введите команду
init dotnet user-secretsЭто добавит GUID UserSecretsId в ваш файл .csproj.
Затем вы можете сохранить свой секрет с помощью команды user-secrets set, например:
dotnet user-secrets set MyConnectionString "my-connection-string"Чтобы получить секретное значение в модульном тесте, просто используйте ConfigurationBuilder и вызовите AddUserSecrets, используя любой класс из вашей сборки в качестве аргумента типа. Затем вы сможете получить доступ к секретам по имени в экземпляре конфигурации и получите значение null, если секрет отсутствует.
using Microsoft.Extensions.Configuration;Заметьте, что для этого вам понадобится установить NuGet-пакет
// ...
var config = new ConfigurationBuilder()
.AddUserSecrets<MyUnitTests>()
.Build();
var connectionString = config["MyConnectionString"];
Microsoft.Extensions.Configuration.UserSecrets
.Если вы запускаете тесты в конвейере CI/CD, можно использовать переменные среды машины, на которой запущен конвейер. Просто добавьте вызов
.AddEnvironmentVariables()
в ConfigurationBuilder
.Источник: https://markheath.net/post/use-secrets-in-unit-tests
👍17
День 1669.
Сертификат Microsoft. Доступ к Microsoft Learn
Microsoft добавили возможность открывать и исследовать портал Microsoft Learn во время сдачи сертификационных экзаменов. Этот ресурс будет доступен для всех ролевых и специализированных экзаменов на всех языках к середине сентября.
В повседневной жизни и работе нам часто нужно посмотреть что-то, что мы могли забыть или в чём мы не уверены. Теперь это возможно и при сдаче экзамена на сертификат Microsoft. В Microsoft расценивают портал, как вспомогательный ресурс, очень похожий на калькулятор. Поэтому предоставляют к нему доступ, однако время экзамена при этом не будет увеличено. Вопросы останутся прежними, они будут сконцентрированы на жизненных проблемах или сценариях, для решения которых требуется реальный опыт. В результате этот ресурс предназначен для ответов на вопросы, описывающих проблемы, для решения которых вам может потребоваться что-то поискать в Microsoft Learn. Использовать ресурс, чтобы ответить на все вопросы, не получится.
Вот некоторые детали:
- У вас будет доступ ко всему домену Learn.microsoft.com, кроме секции вопросов и ответов и вашего профиля (вы не сможете войти в систему).
- Время экзамена не будет добавлено. Таймер экзамена продолжит идти, пока вы будете искать в «Learn» необходимую вам информацию.
- Ресурс будет доступен только для ролевых экзаменов, но не для экзаменов по основам.
- Ресурс будет доступен на тех же языках, на которых доступен экзамен.
Чтобы использовать Learn во время экзамена, нажмите на кнопку Microsoft Learn, доступную на экране вопросов экзамена. Microsoft Learn откроется в панели справа от экзаменационного вопроса. Вы можете перемещаться по веб-сайту, как обычно, и развернуть его на весь экран, если хотите. Вы можете открыть несколько вкладок сайта Microsoft Learn и переходить к различным частям сайта. Просмотр страниц ограничен доменом Microsoft Learn. Хотя сайт содержит ссылки на другие веб-страницы, такие как GitHub, при попытке перехода на другие домены в окне экзамена появится сообщение о том, что сайт недоступен.
Microsoft стремится улучшить общий процесс экзамена, чтобы каждый, кто хочет сдать сертификационный экзамен Microsoft, мог сделать это без каких-либо препятствий и продемонстрировать свой опыт для востребованных должностей.
Поэтому, если вы хотели сдать сертификационный экзамен Microsoft, но не решались из-за боязни не вспомнить какие-нибудь детали, теперь этот барьер убран. По-моему, это отличное решение, особенно если готовиться к экзамену, используя сам портал Microsoft Learn, и хорошенько его изучить.
Источник: https://techcommunity.microsoft.com/t5/microsoft-learn-blog/introducing-a-new-resource-for-all-role-based-microsoft/ba-p/3500870
Сертификат Microsoft. Доступ к Microsoft Learn
Microsoft добавили возможность открывать и исследовать портал Microsoft Learn во время сдачи сертификационных экзаменов. Этот ресурс будет доступен для всех ролевых и специализированных экзаменов на всех языках к середине сентября.
В повседневной жизни и работе нам часто нужно посмотреть что-то, что мы могли забыть или в чём мы не уверены. Теперь это возможно и при сдаче экзамена на сертификат Microsoft. В Microsoft расценивают портал, как вспомогательный ресурс, очень похожий на калькулятор. Поэтому предоставляют к нему доступ, однако время экзамена при этом не будет увеличено. Вопросы останутся прежними, они будут сконцентрированы на жизненных проблемах или сценариях, для решения которых требуется реальный опыт. В результате этот ресурс предназначен для ответов на вопросы, описывающих проблемы, для решения которых вам может потребоваться что-то поискать в Microsoft Learn. Использовать ресурс, чтобы ответить на все вопросы, не получится.
Вот некоторые детали:
- У вас будет доступ ко всему домену Learn.microsoft.com, кроме секции вопросов и ответов и вашего профиля (вы не сможете войти в систему).
- Время экзамена не будет добавлено. Таймер экзамена продолжит идти, пока вы будете искать в «Learn» необходимую вам информацию.
- Ресурс будет доступен только для ролевых экзаменов, но не для экзаменов по основам.
- Ресурс будет доступен на тех же языках, на которых доступен экзамен.
Чтобы использовать Learn во время экзамена, нажмите на кнопку Microsoft Learn, доступную на экране вопросов экзамена. Microsoft Learn откроется в панели справа от экзаменационного вопроса. Вы можете перемещаться по веб-сайту, как обычно, и развернуть его на весь экран, если хотите. Вы можете открыть несколько вкладок сайта Microsoft Learn и переходить к различным частям сайта. Просмотр страниц ограничен доменом Microsoft Learn. Хотя сайт содержит ссылки на другие веб-страницы, такие как GitHub, при попытке перехода на другие домены в окне экзамена появится сообщение о том, что сайт недоступен.
Microsoft стремится улучшить общий процесс экзамена, чтобы каждый, кто хочет сдать сертификационный экзамен Microsoft, мог сделать это без каких-либо препятствий и продемонстрировать свой опыт для востребованных должностей.
Поэтому, если вы хотели сдать сертификационный экзамен Microsoft, но не решались из-за боязни не вспомнить какие-нибудь детали, теперь этот барьер убран. По-моему, это отличное решение, особенно если готовиться к экзамену, используя сам портал Microsoft Learn, и хорошенько его изучить.
Источник: https://techcommunity.microsoft.com/t5/microsoft-learn-blog/introducing-a-new-resource-for-all-role-based-microsoft/ba-p/3500870
👍10
День 1670. #ЗаметкиНаПолях
Неожиданное Поведение Enum.TryParse
Перечисления — это очень простые структуры, но некоторые функции, такие как Enum.TryParse, могут вести себя неожиданно. Сегодня рассмотрим, в чём дело, и как это исправить.
Enum.TryParse «преобразует строковое представление имени или числового значения одной или нескольких перечислимых констант в эквивалентный перечислимый объект. Возвращаемое значение указывает, удалось ли преобразование».
Итак, если у нас есть такое перечисление:
Что делать?
Используйте
Неожиданное Поведение Enum.TryParse
Перечисления — это очень простые структуры, но некоторые функции, такие как Enum.TryParse, могут вести себя неожиданно. Сегодня рассмотрим, в чём дело, и как это исправить.
Enum.TryParse «преобразует строковое представление имени или числового значения одной или нескольких перечислимых констант в эквивалентный перечислимый объект. Возвращаемое значение указывает, удалось ли преобразование».
Итак, если у нас есть такое перечисление:
public enum WeekendИ мы вызываем функцию:
{
Saturday = 0,
Sunday = 1
}
var couldParse =Пока всё нормально, но вот что интересно. Если вы укажете значение, которое не является частью перечисления, это всё равно будет работать:
Enum.TryParse("1", out Weekend day);
Console.WriteLine($"Удача: {couldParse}");
Console.WriteLine($"Значение: {day}");
//Вывод:
Удача: True
Значение: Sunday
var couldParse =И хотя «
Enum.TryParse("3", out Weekend day);
//Вывод:
Удача: True
Значение: 3
Значение: 3
» может иметь смысл, так как вы также можете делать вещи, вродеvar myValue = (WeekendDay)3;кажется странным, что функция возвращает true и сообщает, что смогла без проблем преобразовать аргумент.
Что делать?
Используйте
Enum.IsDefined
, чтобы проверить, находится ли данное значение в правильном диапазоне. С помощью Enum.IsDefined
мы можем проверить, правильно ли значение для данного перечисления.var couldParse =Источник: https://steven-giesel.com/blogPost/64d479f1-823f-4fc7-a56a-2b1ff06dcf72
Enum.TryParse("3", out Weekend day);
if (couldParse
&& Enum.IsDefined(typeof(Weekend), day))
{
// Только здесь мы уверены в
// корректности значения Weekend
}
👍50
День 1671. #ЗаметкиНаПолях
Атрибуты From… в .NET Web API. Начало
Несмотря на то, что ASP.NET «из коробки» неплохо справляется с привязкой параметров методов действий контроллеров или свойств модели, мы можем детально контролировать, откуда мы хотим получить тот или иной параметр или свойство с помощью атрибутов [From<…>].
1. FromQuery
Атрибут FromQuery используется для получения параметра из строки запроса. Мы можем добавить атрибут FromQuery к параметру метода действия, и по умолчанию он будет сопоставлять имя параметра метода с соответствующим именем параметра строки запроса.
В примере ниже, если мы выполним запрос GET к
2. FromHeader
Атрибут FromHeader сопоставляет параметр с соответствующим заголовком запроса на основе имени. Примером этого является использование аутентификации. Если мы используем аутентификацию JWT в веб-API, нам нужно добавить в запрос заголовок авторизации. Если мы хотим получить значение заголовка авторизации, мы можем добавить параметр метода authorization с атрибутом FromHeader.
3. FromForm
Атрибут FromForm работает с запросами POST, если используется тип контента multipart/form-data или x-www-url-encoded. Точно так же, он сопоставит имя поля формы с именем параметра метода. Используя параметр атрибута Name, можно задать требуемое имя поля формы для сопоставления.
FromRoute используется, если атрибут маршрута используется как часть действия. Добавив FromRoute к параметру действия, можно получить значение на основе имени атрибута маршрута. В следующем примере имеется атрибут маршрута с именем {category}. По умолчанию FromRoute сопоставит его атрибут с параметром метода действия category, что также можно переопределить с помощью параметра атрибута Name:
Источник: https://www.roundthecode.com/dotnet-tutorials/fromquery-fromform-what-do-the-net-web-api-attributes-do
Атрибуты From… в .NET Web API. Начало
Несмотря на то, что ASP.NET «из коробки» неплохо справляется с привязкой параметров методов действий контроллеров или свойств модели, мы можем детально контролировать, откуда мы хотим получить тот или иной параметр или свойство с помощью атрибутов [From<…>].
1. FromQuery
Атрибут FromQuery используется для получения параметра из строки запроса. Мы можем добавить атрибут FromQuery к параметру метода действия, и по умолчанию он будет сопоставлять имя параметра метода с соответствующим именем параметра строки запроса.
В примере ниже, если мы выполним запрос GET к
/api/from-api/from-query?page=4
, параметр page получит значение 4, и это значение будет возвращено как часть ответа:[ApiController]Можно добавить необязательный параметр атрибута Name, если имя параметра метода действия отличается от имени в строке запроса:
[Route("api/from-api")]
public class FromApiController : Controller
{
[HttpGet("from-query")]
public IActionResult FromQuery([FromQuery] int page)
{
return Ok(new { page });
}
}
public IActionResult FromQuery(Тогда
[FromQuery(Name = "p")] int page)
/api/from-api/from-query?p=8
задаст параметру page значение 8.2. FromHeader
Атрибут FromHeader сопоставляет параметр с соответствующим заголовком запроса на основе имени. Примером этого является использование аутентификации. Если мы используем аутентификацию JWT в веб-API, нам нужно добавить в запрос заголовок авторизации. Если мы хотим получить значение заголовка авторизации, мы можем добавить параметр метода authorization с атрибутом FromHeader.
public IActionResult FromHeader(Аналогично FromQuery, мы можем использовать необязательный параметр атрибута Name, если хотим, чтобы имя параметра метода отличалось от имени заголовка.
[FromHeader] string authorization)
{
…
}
3. FromForm
Атрибут FromForm работает с запросами POST, если используется тип контента multipart/form-data или x-www-url-encoded. Точно так же, он сопоставит имя поля формы с именем параметра метода. Используя параметр атрибута Name, можно задать требуемое имя поля формы для сопоставления.
public IActionResult FromForm([FromForm] string name)4. FromRoute
{
…
}
FromRoute используется, если атрибут маршрута используется как часть действия. Добавив FromRoute к параметру действия, можно получить значение на основе имени атрибута маршрута. В следующем примере имеется атрибут маршрута с именем {category}. По умолчанию FromRoute сопоставит его атрибут с параметром метода действия category, что также можно переопределить с помощью параметра атрибута Name:
[HttpGet("from-route/{category}")]Окончание следует…
public IActionResult FromRoute(
[FromRoute(Name="category")] string name)
{
…
}
Источник: https://www.roundthecode.com/dotnet-tutorials/fromquery-fromform-what-do-the-net-web-api-attributes-do
👍21
День 1672. #ЗаметкиНаПолях
Атрибуты From… в .NET Web API. Окончание
Начало
Атрибут ApiController
Атрибут ApiController добавляется к контроллеру, когда методы действия внутри него используются для обслуживания ответов API. Он настраивает функции и поведение методов действий контроллера для работы с API, облегчая жизнь разработчику, например, выдачу ответа HTTP 400, если ModelState недействителен, или выдачу деталей проблемы при ошибках.
5. FromBody
Атрибут FromBody используется для извлечения информации из тела запроса, когда тип контента в запросе указан как
FromBody можно использовать только для одного параметра действия. После того как поток запроса прочитан средством форматирования ввода, он больше не доступен для повторного чтения для привязки других параметров через FromBody. Таким образом, если в теле JSON передается более одного значения, их необходимо добавить в один класс и использовать его в качестве типа для параметра действия.
Когда FromBody применяется к параметру сложного типа, любые атрибуты источника привязки, применённые к его свойствам, игнорируются. Например, следующее действие Create указывает, что его параметр pet заполняется из тела:
- Атрибут FromQuery игнорируется.
- Свойство Breed не заполняется из параметра строки запроса.
Средства форматирования ввода читают только тело и не понимают атрибуты источника привязки. Если подходящее значение найдено в теле, это значение используется для заполнения свойства Breed.
6. FromServices
Атрибут FromServices не имеет ничего общего с HTTP-запросом. Вместо этого он позволяет использовать параметр метода действия для сопоставления с сервисом из контейнера внедрения зависимостей. Его цель — предоставить альтернативу внедрению через конструктор, когда вам нужен сервис только при вызове определённого метода.
Если экземпляр типа не зарегистрирован в контейнере внедрения зависимостей, приложение выдаст исключение при попытке привязать параметр. Чтобы сделать параметр необязательным, используйте один из следующих подходов:
- Сделайте параметр обнуляемым (в теле метода при обращении к параметру убедитесь, что он не null).
- Установите значение по умолчанию для параметра.
Атрибут FromServices также не требуется, если контроллер помечен атрибутом ApiController.
Источники:
- https://www.roundthecode.com/dotnet-tutorials/fromquery-fromform-what-do-the-net-web-api-attributes-do
- https://learn.microsoft.com/en-us/aspnet/core/mvc/models/model-binding
Атрибуты From… в .NET Web API. Окончание
Начало
Атрибут ApiController
Атрибут ApiController добавляется к контроллеру, когда методы действия внутри него используются для обслуживания ответов API. Он настраивает функции и поведение методов действий контроллера для работы с API, облегчая жизнь разработчику, например, выдачу ответа HTTP 400, если ModelState недействителен, или выдачу деталей проблемы при ошибках.
5. FromBody
Атрибут FromBody используется для извлечения информации из тела запроса, когда тип контента в запросе указан как
application/json
, application/xml
и т.п. Среда выполнения ASP.NET Core делегирует ответственность за чтение тела средству форматирования ввода (по умолчанию используется формат JSON). Для XML его можно добавить следующим образом:builder.Services.AddControllers()Если контроллер имеет атрибут ApiController, необходимость в использовании атрибута FromBody отпадает.
.AddXmlSerializerFormatters();
FromBody можно использовать только для одного параметра действия. После того как поток запроса прочитан средством форматирования ввода, он больше не доступен для повторного чтения для привязки других параметров через FromBody. Таким образом, если в теле JSON передается более одного значения, их необходимо добавить в один класс и использовать его в качестве типа для параметра действия.
Когда FromBody применяется к параметру сложного типа, любые атрибуты источника привязки, применённые к его свойствам, игнорируются. Например, следующее действие Create указывает, что его параметр pet заполняется из тела:
public ActionResult<Pet> Create([FromBody] Pet pet)Класс Pet указывает, что его свойство Breed заполняется из параметра строки запроса:
public class PetЗдесь:
{
public string Name { get; set; };
[FromQuery]
public string Breed { get; set; };
}
- Атрибут FromQuery игнорируется.
- Свойство Breed не заполняется из параметра строки запроса.
Средства форматирования ввода читают только тело и не понимают атрибуты источника привязки. Если подходящее значение найдено в теле, это значение используется для заполнения свойства Breed.
6. FromServices
Атрибут FromServices не имеет ничего общего с HTTP-запросом. Вместо этого он позволяет использовать параметр метода действия для сопоставления с сервисом из контейнера внедрения зависимостей. Его цель — предоставить альтернативу внедрению через конструктор, когда вам нужен сервис только при вызове определённого метода.
Если экземпляр типа не зарегистрирован в контейнере внедрения зависимостей, приложение выдаст исключение при попытке привязать параметр. Чтобы сделать параметр необязательным, используйте один из следующих подходов:
- Сделайте параметр обнуляемым (в теле метода при обращении к параметру убедитесь, что он не null).
- Установите значение по умолчанию для параметра.
Атрибут FromServices также не требуется, если контроллер помечен атрибутом ApiController.
Источники:
- https://www.roundthecode.com/dotnet-tutorials/fromquery-fromform-what-do-the-net-web-api-attributes-do
- https://learn.microsoft.com/en-us/aspnet/core/mvc/models/model-binding
👍14
День 1673. #ЗаметкиНаПолях
Отправляем Письма с Помощью FluentEmail
В вашем приложении зарегистрировался новый пользователь? Код подтверждения должен быть отправлен на его email. Пользователь забыл пароль? Нужно отправить ему ссылку для сброса пароля. Сегодня приложения не могут существовать без отправки электронной почты. Поэтому нужно что-то легко и быстро настраиваемое для отправки электронных писем.
FluentEmail — популярная библиотека с открытым исходным кодом для отправки email из приложений .NET. Он предоставляет fluent-интерфейс, т.е. мы можем легко создать сообщение, добавить получателей, установить тему и т. д., используя цепочку методов.
Сначала нужно добавить в проект NuGet-пакеты FluentEmail.Core и FluentEmail.Smtp. Теперь создать и отправить email очень просто:
Доступны наиболее распространённые методы:
- .To(string emailAddress) — добавить получателей.
- .SetFrom(string emailAddress) — изменить адрес отправителя.
- .CC/BCC(string emailAddress) — добавление CC или BCC.
- .Subject(string subject) — тема.
- .Body(string body) — тело сообщения.
- .Attach(Attachment attachment) — вложения.
- .UsingTemplate(string template, T model, bool isHtml = true) — использовать шаблон (см. ниже).
- .SendAsync() — отправить, используя настроенного отправителя (см. ниже).
Более правильным подходом будет настроить отправителя и шаблон в DI-контейнере:
- AddSmtpSender() – настраивает провайдера отправителя SmtpSender.
- AddRazorRenderer() – настраивает провайдера шаблонов RazorRenderer.
Использование Razor-шаблонов сообщений – одна из самых популярных функций FluentEmail. Чтобы её использовать, добавьте NuGet-пакет FluentEmail.Razor. RazorRenderer поддерживает любой код Razor. Используя шаблоны, вы можете заменить вызов
-
-
FluentEmail позволяет вам подключить популярные провайдеры отправки email (или создать собственный, реализовав интерфейс ISender). Чтобы использовать отправителя, добавьте провайдера и настройте его в DI-контейнере. Доступны следующие основные провайдеры:
- SMTP – стандартный клиент System.Net.Mail.SmtpClient
- Mailgun
- SendGrid
- MimeKit
Например, добавить провайдера SendGrid можно, установив NuGet-пакет FluentEmail.SendGrid и вызвав:
- https://stefandjokic.tech/blog.html
- https://lukelowrey.com/send-email-in-dotnet-core-with-fluent-email/
Отправляем Письма с Помощью FluentEmail
В вашем приложении зарегистрировался новый пользователь? Код подтверждения должен быть отправлен на его email. Пользователь забыл пароль? Нужно отправить ему ссылку для сброса пароля. Сегодня приложения не могут существовать без отправки электронной почты. Поэтому нужно что-то легко и быстро настраиваемое для отправки электронных писем.
FluentEmail — популярная библиотека с открытым исходным кодом для отправки email из приложений .NET. Он предоставляет fluent-интерфейс, т.е. мы можем легко создать сообщение, добавить получателей, установить тему и т. д., используя цепочку методов.
Сначала нужно добавить в проект NuGet-пакеты FluentEmail.Core и FluentEmail.Smtp. Теперь создать и отправить email очень просто:
var email = await EmailЗаметьте, что From – единственный статический метод, поэтому в этом примере должен идти первым.
.From("[email protected]")
.To("[email protected]")
.Subject("Hi")
.Body("Hello world!")
.SendAsync();
Доступны наиболее распространённые методы:
- .To(string emailAddress) — добавить получателей.
- .SetFrom(string emailAddress) — изменить адрес отправителя.
- .CC/BCC(string emailAddress) — добавление CC или BCC.
- .Subject(string subject) — тема.
- .Body(string body) — тело сообщения.
- .Attach(Attachment attachment) — вложения.
- .UsingTemplate(string template, T model, bool isHtml = true) — использовать шаблон (см. ниже).
- .SendAsync() — отправить, используя настроенного отправителя (см. ниже).
Более правильным подходом будет настроить отправителя и шаблон в DI-контейнере:
builder.Services- .AddFluentEmail() – настраивает FluentEmail с адресом отправителя по умолчанию.
.AddFluentEmail("[email protected]")
.AddRazorRenderer()
.AddSmtpSender(…);
- AddSmtpSender() – настраивает провайдера отправителя SmtpSender.
- AddRazorRenderer() – настраивает провайдера шаблонов RazorRenderer.
Использование Razor-шаблонов сообщений – одна из самых популярных функций FluentEmail. Чтобы её использовать, добавьте NuGet-пакет FluentEmail.Razor. RazorRenderer поддерживает любой код Razor. Используя шаблоны, вы можете заменить вызов
.Body(…)
в примере выше на один из следующих:-
UsingTemplate<T>(string template, T model)
– использует шаблон из строки template (не очень удобно писать код Razor внутри простой строки, но подойдёт для простых шаблонов).-
UsingTemplateFromFile<T>(string fileName, T model)
– позволяет указать путь к файлу шаблона – обычной странице .cshtml.FluentEmail позволяет вам подключить популярные провайдеры отправки email (или создать собственный, реализовав интерфейс ISender). Чтобы использовать отправителя, добавьте провайдера и настройте его в DI-контейнере. Доступны следующие основные провайдеры:
- SMTP – стандартный клиент System.Net.Mail.SmtpClient
- Mailgun
- SendGrid
- MimeKit
Например, добавить провайдера SendGrid можно, установив NuGet-пакет FluentEmail.SendGrid и вызвав:
builder.ServicesИсточники:
.AddFluentEmail("[email protected]")
.AddRazorRenderer()
.AddSendGridSender("apikey");
- https://stefandjokic.tech/blog.html
- https://lukelowrey.com/send-email-in-dotnet-core-with-fluent-email/
👍31
День 1674. #Безопасность
Политика Безопасности Контента. Начало
Политика безопасности контента (Content Security Policy, CSP) представляет собой HTTP-заголовок Content-Security-Policy, который указывает браузерам, откуда загружать (и, в случае JavaScript, исполнять) контент, что может сделать почти невозможным осуществление межсайтового скриптинга. Значение заголовка состоит из директив и связанных значений.
Основная директива
*Источник определяется как следующие три значения:
- схема – http: или https:;
- полностью определённое имя домена – www.example.com;
- порт – по умолчанию 80 для HTTP или 443 для HTTPS (если используется порт по умолчанию, то обычно он не является частью значения источника).
Если все три части различных источников идентичны, значит они совпадают. Например, у www.example.com и example.com разный источник, поскольку имена доменов не совпадают.
Кроме HTTP-заголовка можно использовать тег
CSP определяет большое количество директив для различных видов ресурсов:
- base-uri – значения или пути, разрешенные для
- child-src - фреймы и веб-воркеры,
- connect-src - запросы HTTP и WebSocket,
- font-src – шрифты,
- form-action – значения для атрибута action элементов
- img-src – изображения,
- media-src - аудио- и видеофайлы,
- object-src – плагины,
- script-src - код JavaScript,
- style-src - cтили CSS,
и другие.
Специализированные директивы переопределяют значения
В заголовке директивы разделяются точкой с запятой, а их значения пробелами, например:
Для указания источника есть следующие варианты:
- сайт –
- путь –
- полный URI –
- подстановочный знак (
Рекомендуется использовать наиболее строгое указание источника, например, не разрешать все ресурсы из сети CDN.
Продолжение следует…
Источник: Кристиан Венц “Безопасность ASP.NET Core”. М.: ДМК Пресс, 2023. Глава 2.
Политика Безопасности Контента. Начало
Политика безопасности контента (Content Security Policy, CSP) представляет собой HTTP-заголовок Content-Security-Policy, который указывает браузерам, откуда загружать (и, в случае JavaScript, исполнять) контент, что может сделать почти невозможным осуществление межсайтового скриптинга. Значение заголовка состоит из директив и связанных значений.
Основная директива
default-src
предоставляет браузеру список всех действительных источников* или URI ресурсов.*Источник определяется как следующие три значения:
- схема – http: или https:;
- полностью определённое имя домена – www.example.com;
- порт – по умолчанию 80 для HTTP или 443 для HTTPS (если используется порт по умолчанию, то обычно он не является частью значения источника).
Если все три части различных источников идентичны, значит они совпадают. Например, у www.example.com и example.com разный источник, поскольку имена доменов не совпадают.
Кроме HTTP-заголовка можно использовать тег
<meta>
:<meta http-equiv="Content-Security-Policy" content="default-src 'self'">Однако, это не очень удобно, когда значение директивы длинное. Кроме того, не будут работать некоторые функции CSP.
CSP определяет большое количество директив для различных видов ресурсов:
- base-uri – значения или пути, разрешенные для
<base href="">
;- child-src - фреймы и веб-воркеры,
- connect-src - запросы HTTP и WebSocket,
- font-src – шрифты,
- form-action – значения для атрибута action элементов
<form>
;- img-src – изображения,
- media-src - аудио- и видеофайлы,
- object-src – плагины,
- script-src - код JavaScript,
- style-src - cтили CSS,
и другие.
Специализированные директивы переопределяют значения
default-src
.В заголовке директивы разделяются точкой с запятой, а их значения пробелами, например:
default-src 'self'; style-src 'self' https://cdn.jsdelivr.netЗдесь мы разрешаем использовать ресурсы только из того же источника, что и сама страница (
'self'
), а также разрешаем получать стили из сети доставки контента (CDN). Заметьте, что для style-src
также указано значение 'self'
, чтобы была возможность использовать локальные файлы стилей (т.к. style-src
полностью перезаписывает значение default-src
).Для указания источника есть следующие варианты:
- сайт –
https://example.com
;- путь –
https://example.com/assets/
(завершающий слеш обязателен для указания папки, а не файла с таким именем);- полный URI –
https://example.com/assets/style.css
;- подстановочный знак (
*
).Рекомендуется использовать наиболее строгое указание источника, например, не разрешать все ресурсы из сети CDN.
Продолжение следует…
Источник: Кристиан Венц “Безопасность ASP.NET Core”. М.: ДМК Пресс, 2023. Глава 2.
👍2
День 1675. #Безопасность
Политика Безопасности Контента. Продолжение
Начало
Встроенный код
Если существует директива CSP
При этом
будет работать. Обычно лучше избегать встроенного кода. Вынесите код JavaScript и CSS во внешние файлы.
Однако, если нужно активировать встроенный контент, есть несколько вариантов:
1. Атрибут nonce (одноразовый номер)
Случайный одноразовый токен (например, GUID), который добавляется в HTTP заголовок:
и во все элементы
Нужно вычислить хеш SHA256, SHA384 или SHA512 контента элемента
Использование хэша не распространяется на:
- атрибуты обработчиков событий (например,
- ссылки JavaScript: (
- атрибуты стилей (
Для активации этих функций, к значениям политики
Также перестанет работать динамическое выполнение кода (eval(), setInterval(), setTimeout() со строковыми аргументами и т.п.). Чтобы включить это, нужно добавить
3. Значение 'unsafe-inline'.
Разрешает исполнение встроенного кода (практически сводя на нет преимущества CSP).
Проверка кода JavaScript с помощью Subresource Integrity (SRI)
Если вы загружаете файл JavaScript со стороннего сервера, то можно проверить, что он не был подделан. Присвойте атрибуту integrity тега <script> хэш содержимого файла JavaScript:
Окончание следует…
Источник: Кристиан Венц “Безопасность ASP.NET Core”. М.: ДМК Пресс, 2023. Глава 2.
Политика Безопасности Контента. Продолжение
Начало
Встроенный код
Если существует директива CSP
default-src
или style-src
, то встроенные стили перестают работать. Аналогично, при наличии default-src
или script-src
встроенный код JavaScript больше выполняться не будет. Это позволяет защититься от внедрения кода вида <script>/* вредоносный код */</script>
. При этом
<script src="script.js"></script>
будет работать. Обычно лучше избегать встроенного кода. Вынесите код JavaScript и CSS во внешние файлы.
Однако, если нужно активировать встроенный контент, есть несколько вариантов:
1. Атрибут nonce (одноразовый номер)
Случайный одноразовый токен (например, GUID), который добавляется в HTTP заголовок:
default-src 'self'; style-src 'self' 'nonce-123456'; script-src 'self' 'nonce-123456
'и во все элементы
<script>
и <style>
, где используются встроенный код: <script nonce="123456'">…</script>2. Хэш контента элемента
Нужно вычислить хеш SHA256, SHA384 или SHA512 контента элемента
<script>
или <style>
, включая разрывы строк и другие пробельные символы, и добавить в HTTP-заголовок значение 'sha<алгоритм>-<хэш>':default-src 'self'; script-src 'self' 'sha256-nzw…='Теперь эта политика явно разрешает встроенный код JavaScript, соответствующий хэшу.
Использование хэша не распространяется на:
- атрибуты обработчиков событий (например,
onclick
);- ссылки JavaScript: (
<a href="JavaScript:…">
);- атрибуты стилей (
style="…"
).Для активации этих функций, к значениям политики
script-src
или style-src
надо добавить константу 'unsafe-hashes'
(в дополнение к хэшам кода в этих атрибутах).Также перестанет работать динамическое выполнение кода (eval(), setInterval(), setTimeout() со строковыми аргументами и т.п.). Чтобы включить это, нужно добавить
'unsafe-eval'
.3. Значение 'unsafe-inline'.
Разрешает исполнение встроенного кода (практически сводя на нет преимущества CSP).
Проверка кода JavaScript с помощью Subresource Integrity (SRI)
Если вы загружаете файл JavaScript со стороннего сервера, то можно проверить, что он не был подделан. Присвойте атрибуту integrity тега <script> хэш содержимого файла JavaScript:
<script src="https://code.jquery.com/jquery-3.6.0.min.js"Если содержимое файла JavaScript не совпадает с хэшем, браузер откажется выполнить код.
integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="></script>
Окончание следует…
Источник: Кристиан Венц “Безопасность ASP.NET Core”. М.: ДМК Пресс, 2023. Глава 2.
👍9
День 1676. #Безопасность
Политика Безопасности Контента. Окончание
Начало
Продолжение
Отправка отчётов
Часто полезно знать, когда политика CSP нарушается. Это означает, что либо вы не разрешили использование какого-либо источника, либо есть уязвимость, которая активно эксплуатируется.
Директива report-uri заставит браузер отправлять POST-запрос на выбранную конечную точку при нарушении одной из политик:
Браузер отправит отчёт в формате JSON на эту конечную точку (которая также может находиться на другом домене) с информацией, какая политика была нарушена, какой файл (скрипт) её нарушил, в каком месте кода страницы он был вызван, и т.п. Существуют коммерческие системы, которые будут принимать ваши отчёты CSP и форматировать их в приятные UI представления (например, https://report-uri.com/). Стоит ли отправлять информацию о безопасности вашего сайта третьей стороне – решать вам.
Однако, можно не дожидаться, пока в производственной среде что-то перестанет работать, прежде чем исправлять это. HTTP-заголовок
При добавлении политик CSP к уже имеющемуся сайту полезно начать с использования заголовка
Затем, по мере получения отчётов либо вносите изменения в сайт, либо ослабляйте политики.
Конечная цель – максимально строгая CSP, насколько это возможно при используемом вами стеке. Обязательно нужно отключить плагины
и базовый URI:
Также стоит рассмотреть возможность ограничения контента JavaScript только теми скриптами, для которых задан одноразовый токен:
Источник: Кристиан Венц “Безопасность ASP.NET Core”. М.: ДМК Пресс, 2023. Глава 2.
Политика Безопасности Контента. Окончание
Начало
Продолжение
Отправка отчётов
Часто полезно знать, когда политика CSP нарушается. Это означает, что либо вы не разрешили использование какого-либо источника, либо есть уязвимость, которая активно эксплуатируется.
Директива report-uri заставит браузер отправлять POST-запрос на выбранную конечную точку при нарушении одной из политик:
default-src 'self'; style-src 'self' https://cdn.jsdelivr.net …; report-uri /csp-reports
Браузер отправит отчёт в формате JSON на эту конечную точку (которая также может находиться на другом домене) с информацией, какая политика была нарушена, какой файл (скрипт) её нарушил, в каком месте кода страницы он был вызван, и т.п. Существуют коммерческие системы, которые будут принимать ваши отчёты CSP и форматировать их в приятные UI представления (например, https://report-uri.com/). Стоит ли отправлять информацию о безопасности вашего сайта третьей стороне – решать вам.
Однако, можно не дожидаться, пока в производственной среде что-то перестанет работать, прежде чем исправлять это. HTTP-заголовок
Сontent-Security-Policy-Report-Only
подойдёт для тестирования политик. В отличие от заголовка Content-Security-Policy
, он не будет применять политики безопасности контента, а просто будет сообщать о найденных нарушениях политик на заданную конечную точку (если она задана в report-uri
).При добавлении политик CSP к уже имеющемуся сайту полезно начать с использования заголовка
Сontent-Security-Policy-Report-Only
и политики, запрещающей всё. Для этого используется константа 'none'
:default-src 'none'; form-action 'none'; report-uri /csp-reports
Затем, по мере получения отчётов либо вносите изменения в сайт, либо ослабляйте политики.
Конечная цель – максимально строгая CSP, насколько это возможно при используемом вами стеке. Обязательно нужно отключить плагины
и базовый URI:
object-src 'none'; base-uri 'none'
Также стоит рассмотреть возможность ограничения контента JavaScript только теми скриптами, для которых задан одноразовый токен:
script-src 'nonce-…'
Источник: Кристиан Венц “Безопасность ASP.NET Core”. М.: ДМК Пресс, 2023. Глава 2.
👍9
День 1677. #PostgresTips
Советы по Postgres для Начинающих
7. Убедитесь, что контрольные суммы данных включены.
Целостность данных является краеугольным камнем любой базы данных. Без уверенности в точности и согласованности данных даже самые совершенные структуры и алгоритмы БД станут бесполезными. Именно здесь контрольные суммы данных в Postgres играют решающую роль.
Что это?
В контексте БД контрольная сумма — это значение, полученное из суммы всех байтов в блоке данных. Если контрольные суммы данных включены, Postgres использует их для проверки целостности данных, хранящихся на диске. Когда данные записываются на диск, Postgres вычисляет и сохраняет значение контрольной суммы. Позже, когда эти данные считываются обратно в память, Postgres пересчитывает контрольную сумму и сравнивает её с сохранённым значением, чтобы убедиться, что данные не были повреждены.
Почему это важно?
Повреждение на уровне диска может быть вызвано различными факторами: от сбоев оборудования до ошибок ПО. Если включены контрольные суммы, Postgres может идентифицировать повреждённые данные до того, как это повлияет на ваше приложение или приведёт к более серьезным проблемам.
Активация и накладные расходы
Важно отметить, что контрольные суммы необходимо активировать во время создания кластера БД (initdb). Их невозможно включить для существующего кластера БД без дампа и восстановления данных или без использования специального инструмента pg_checksums (для этого потребуется некоторый опыт). Накладные расходы, связанные с контрольными суммами, относительно малы, особенно по сравнению с преимуществами обеспечения целостности данных.
8. Настройте автоочистку для частых запусков и более быстрого выполнения.
Процесс автоочистки (autovacuum) в Postgres похож на бригаду уборщиков для БД. Он работает незаметно, очищая старые данные и освобождая место для новых данных, обеспечивая эффективность БД.
Что это?
Каждая операция INSERT, UPDATE или DELETE в Postgres создаёт новую версию строки (в случае DELETE помечает строку как удалённую). Со временем старые версии строк накапливаются, и их необходимо очищать. Autovacuum выполняет эту очистку, освобождая место для хранения и удаляя «мёртвые» строки. Он также отвечает за поддержание актуальности статистики таблиц и предотвращение инцидентов, связанных с переносом идентификаторов транзакций.
Почему это важно?
Без регулярной автоматической очистки БД может страдать от раздувания — неиспользуемого пространства, которое удерживает БД, что может замедлять запросы и тратить дисковое пространство. Другая проблема — устаревшая статистика, которая может приводить к неоптимальному выбору плана запроса и снижению производительности.
Как настроить
Настройка автоочистки сводится к тому, чтобы она запускалась чаще и быстрее выполняла свои задачи. По сути, настройку приходится вести в двух направлениях:
- дать автоочистке больше мощности (больше рабочих процессов, большая квоту), т.к. по умолчанию разрешено только 3 рабочих процесса, и они довольно консервативно ограничиваются;
- заставить её срабатывать чаще, т.к., опять же, по умолчанию она срабатывает только при значительных изменениях строк (10-20%); в OLTP базе данных желательно уменьшить этот показатель до 1% или даже ниже.
Источник: https://postgres.ai/blog/20230722-10-postgres-tips-for-beginners
Советы по Postgres для Начинающих
7. Убедитесь, что контрольные суммы данных включены.
Целостность данных является краеугольным камнем любой базы данных. Без уверенности в точности и согласованности данных даже самые совершенные структуры и алгоритмы БД станут бесполезными. Именно здесь контрольные суммы данных в Postgres играют решающую роль.
Что это?
В контексте БД контрольная сумма — это значение, полученное из суммы всех байтов в блоке данных. Если контрольные суммы данных включены, Postgres использует их для проверки целостности данных, хранящихся на диске. Когда данные записываются на диск, Postgres вычисляет и сохраняет значение контрольной суммы. Позже, когда эти данные считываются обратно в память, Postgres пересчитывает контрольную сумму и сравнивает её с сохранённым значением, чтобы убедиться, что данные не были повреждены.
Почему это важно?
Повреждение на уровне диска может быть вызвано различными факторами: от сбоев оборудования до ошибок ПО. Если включены контрольные суммы, Postgres может идентифицировать повреждённые данные до того, как это повлияет на ваше приложение или приведёт к более серьезным проблемам.
Активация и накладные расходы
Важно отметить, что контрольные суммы необходимо активировать во время создания кластера БД (initdb). Их невозможно включить для существующего кластера БД без дампа и восстановления данных или без использования специального инструмента pg_checksums (для этого потребуется некоторый опыт). Накладные расходы, связанные с контрольными суммами, относительно малы, особенно по сравнению с преимуществами обеспечения целостности данных.
8. Настройте автоочистку для частых запусков и более быстрого выполнения.
Процесс автоочистки (autovacuum) в Postgres похож на бригаду уборщиков для БД. Он работает незаметно, очищая старые данные и освобождая место для новых данных, обеспечивая эффективность БД.
Что это?
Каждая операция INSERT, UPDATE или DELETE в Postgres создаёт новую версию строки (в случае DELETE помечает строку как удалённую). Со временем старые версии строк накапливаются, и их необходимо очищать. Autovacuum выполняет эту очистку, освобождая место для хранения и удаляя «мёртвые» строки. Он также отвечает за поддержание актуальности статистики таблиц и предотвращение инцидентов, связанных с переносом идентификаторов транзакций.
Почему это важно?
Без регулярной автоматической очистки БД может страдать от раздувания — неиспользуемого пространства, которое удерживает БД, что может замедлять запросы и тратить дисковое пространство. Другая проблема — устаревшая статистика, которая может приводить к неоптимальному выбору плана запроса и снижению производительности.
Как настроить
Настройка автоочистки сводится к тому, чтобы она запускалась чаще и быстрее выполняла свои задачи. По сути, настройку приходится вести в двух направлениях:
- дать автоочистке больше мощности (больше рабочих процессов, большая квоту), т.к. по умолчанию разрешено только 3 рабочих процесса, и они довольно консервативно ограничиваются;
- заставить её срабатывать чаще, т.к., опять же, по умолчанию она срабатывает только при значительных изменениях строк (10-20%); в OLTP базе данных желательно уменьшить этот показатель до 1% или даже ниже.
Источник: https://postgres.ai/blog/20230722-10-postgres-tips-for-beginners
👍13
This media is not supported in your browser
VIEW IN TELEGRAM
День 1678. #ЧтоНовенького
Превью Изображений в Visual Studio
Любой разработчик часто работает с изображениями: локальными, размещёнными в Интернете или в общих сетевых ресурсах, либо существующими только в виде строк в кодировке Base64. В коде мы ссылаемся на них по-разному, но всегда как на строковые значения, которые не показывают нам, как выглядит изображение.
Для Visual Studio теперь есть расширение Image Preview от Мэдса Кристенсена. Когда указатель мыши наводится на ссылку на изображение, появляется всплывающая подсказка, показывающая визуализированное изображение. Поддерживаются GIF, PNG, JPG, ICO и SVG в следующих случаях:
- Абсолютный URL (
- Относительный URL (
- Путь к файлу (
- URI данных (
- URI пакета (
При относительной ссылке, например
Источник
Превью Изображений в Visual Studio
Любой разработчик часто работает с изображениями: локальными, размещёнными в Интернете или в общих сетевых ресурсах, либо существующими только в виде строк в кодировке Base64. В коде мы ссылаемся на них по-разному, но всегда как на строковые значения, которые не показывают нам, как выглядит изображение.
Для Visual Studio теперь есть расширение Image Preview от Мэдса Кристенсена. Когда указатель мыши наводится на ссылку на изображение, появляется всплывающая подсказка, показывающая визуализированное изображение. Поддерживаются GIF, PNG, JPG, ICO и SVG в следующих случаях:
- Абсолютный URL (
http
, https
и ftp
)- Относительный URL (
./
, ../
и /
)- Путь к файлу (
c:\
, c:/
, \
и /
)- URI данных (
data:image/png;base64,…
)- URI пакета (
pack://application:,,,/Images/MyImage.png
)При относительной ссылке, например
/file.png
, расширение попытается разрешить его относительно корневой папки проекта или папки wwwroot в случае проектов ASP.NET.Источник
👍13
День 1679. #ЗаметкиНаПолях #Debugging
Правила Отладки: Понимание Системы
Решение проблем без подлинного их понимания может создать ненужные трудности и поставить под угрозу качество программы. Поэтому крайне важно тщательно понять систему, прежде чем пытаться её исправить. Чтобы добиться этого, триангулируйте дефект, протестировав сценарии, которые должны воспроизводить ошибку, и те, которые не должны воспроизводить её. Продолжайте этот процесс до тех пор, пока не поймете проблему достаточно хорошо, чтобы точно предсказать её возникновение в каждом случае.
1. Читайте документацию
Понимание предполагаемого поведения системы, её конструкции, а иногда и обоснования её конструкции, очень важно. Когда отсутствует понимание какого-либо конкретного аспекта системы, это часто становится основной причиной проблем.
Часто люди пытаются устранить проблемы, не вникая в документацию, просматривая её бегло и сосредотачиваясь только на тех разделах, которые они считают важными, непреднамеренно упуская из виду ключевую подсказку, скрытую в неисследованном разделе, которая могла бы раскрыть основную причину проблемы.
Документация может казаться сложной из-за её размера, но важно в неё тщательно вникать. Часто функция, которая на первый взгляд кажется понятной, может вызывать неожиданные проблемы.
Документация также часто содержит ценную информацию о проблемах, с которыми сталкивались другие. Предупреждения о типичных ошибках оказываются невероятно полезными, даже если вы считаете, что у вас необычная ошибка.
Примеры кода могут помочь, но следует соблюдать осторожность. Они демонстрируют один из способов использования продукта, но могут не придерживаться передовых методов проектирования и не соответствовать реальным приложениям. Простое копирование кода без полного его понимания может привести к появлению ошибок в дальнейшем.
2. Знайте, что разумно
При изучении системы крайне важно иметь чёткое представление о её типичном функционировании. Понимание стандартных операций позволяет эффективно выявлять отклонения или аномалии. Многим сложно выявить проблемы просто потому, что им не хватает фундаментального понимания того, как должна работать система.
3. Знайте дорожную карту
Важно знать структуру системы. Когда определённые части системы считаются «черными ящиками», понимание того, как они должны взаимодействовать с другими компонентами, помогает определить, находится ли проблема внутри ящика или за его пределами.
4. Изучите свои инструменты
Инструменты отладки предоставляют ценную информацию. Чтобы эффективно их использовать, важно освоить три аспекта:
- выбор подходящего инструмента для задачи,
- правильное его использование,
- точная интерпретация результатов.
Понимание ограничений инструментов не менее важно для обеспечения эффективных и успешных процессов отладки.
5. Изучайте подробности
Избегайте предположений. Потратьте время на исследование и получение точной информации. Подробные детали были задокументированы либо вами, либо создателем библиотеки, API или платформы. Неразумно полагаться исключительно на свою память.
Предположения могут вывести вас на ложный путь, где неверная информация может показаться верной, и вы упустите из виду важные проблемы. Вы можете столкнуться с запутанными данными или, что еще хуже, с ложно обнадёживающими данными.
Берите пример с Эйнштейна, который никогда не трудился запоминать свой номер телефона. Он знал, что его всегда можно найти в телефонной книге.
Источник: https://dev.to/rajasegar/debugging-rules-understand-the-system-ho5
Правила Отладки: Понимание Системы
Решение проблем без подлинного их понимания может создать ненужные трудности и поставить под угрозу качество программы. Поэтому крайне важно тщательно понять систему, прежде чем пытаться её исправить. Чтобы добиться этого, триангулируйте дефект, протестировав сценарии, которые должны воспроизводить ошибку, и те, которые не должны воспроизводить её. Продолжайте этот процесс до тех пор, пока не поймете проблему достаточно хорошо, чтобы точно предсказать её возникновение в каждом случае.
1. Читайте документацию
Понимание предполагаемого поведения системы, её конструкции, а иногда и обоснования её конструкции, очень важно. Когда отсутствует понимание какого-либо конкретного аспекта системы, это часто становится основной причиной проблем.
Часто люди пытаются устранить проблемы, не вникая в документацию, просматривая её бегло и сосредотачиваясь только на тех разделах, которые они считают важными, непреднамеренно упуская из виду ключевую подсказку, скрытую в неисследованном разделе, которая могла бы раскрыть основную причину проблемы.
Документация может казаться сложной из-за её размера, но важно в неё тщательно вникать. Часто функция, которая на первый взгляд кажется понятной, может вызывать неожиданные проблемы.
Документация также часто содержит ценную информацию о проблемах, с которыми сталкивались другие. Предупреждения о типичных ошибках оказываются невероятно полезными, даже если вы считаете, что у вас необычная ошибка.
Примеры кода могут помочь, но следует соблюдать осторожность. Они демонстрируют один из способов использования продукта, но могут не придерживаться передовых методов проектирования и не соответствовать реальным приложениям. Простое копирование кода без полного его понимания может привести к появлению ошибок в дальнейшем.
2. Знайте, что разумно
При изучении системы крайне важно иметь чёткое представление о её типичном функционировании. Понимание стандартных операций позволяет эффективно выявлять отклонения или аномалии. Многим сложно выявить проблемы просто потому, что им не хватает фундаментального понимания того, как должна работать система.
3. Знайте дорожную карту
Важно знать структуру системы. Когда определённые части системы считаются «черными ящиками», понимание того, как они должны взаимодействовать с другими компонентами, помогает определить, находится ли проблема внутри ящика или за его пределами.
4. Изучите свои инструменты
Инструменты отладки предоставляют ценную информацию. Чтобы эффективно их использовать, важно освоить три аспекта:
- выбор подходящего инструмента для задачи,
- правильное его использование,
- точная интерпретация результатов.
Понимание ограничений инструментов не менее важно для обеспечения эффективных и успешных процессов отладки.
5. Изучайте подробности
Избегайте предположений. Потратьте время на исследование и получение точной информации. Подробные детали были задокументированы либо вами, либо создателем библиотеки, API или платформы. Неразумно полагаться исключительно на свою память.
Предположения могут вывести вас на ложный путь, где неверная информация может показаться верной, и вы упустите из виду важные проблемы. Вы можете столкнуться с запутанными данными или, что еще хуже, с ложно обнадёживающими данными.
Берите пример с Эйнштейна, который никогда не трудился запоминать свой номер телефона. Он знал, что его всегда можно найти в телефонной книге.
Источник: https://dev.to/rajasegar/debugging-rules-understand-the-system-ho5
👍9
День 1680. #Безопасность
Cookie и Управление Сессиями
Управление сессиями в ASP.NET Core зависит от файлов cookie. Сервер отправляет cookie с использованием HTTP-заголовка Set-Cookie, который содержит имя файла cookie, его значение и необязательные атрибуты, например дату истечения срока действия (по умолчанию cookie истекает при закрытии браузера). Браузер может принять, отклонить файл cookie или спросить пользователя, что делать. Почти всегда действует первый вариант. Отключение файлов cookie в браузере практически не позволяет использовать многие веб-приложения.
Поскольку cookie хранятся в браузере, их значениями легко манипулировать. Нельзя хранить конфиденциальную информацию в файле cookie, например текущее имя пользователя или его привилегии. Управление сессиями использует cookie, но снижает риски манипулирования данными. Сервер хранит уникальный идентификатор сессии, который отправляется клиенту в виде файла cookie. Идентификатор генерируется на сервере, он довольно длинный, и его практически невозможно угадать.
В ASP.NET Core функциональность сессий должна быть активирована явно. В Program.cs нужно вызвать
Браузер отправляет файлы cookie обратно на сервер с каждым последующим запросом, поэтому сервер всегда может идентифицировать сессию и получить доступ к правильным данным. Пока идентификатор сессии не будет украден, процесс безопасен. Но если злоумышленник получает идентификатор, он может выдать себя за пользователя при общении с сервером.
Злоумышленник может украсть идентификатор сессии 3 способами:
1. на стороне клиента, как правило, используя межсайтовый скриптинг;
2. на стороне сервера, но осуществить такую атаку довольно непросто;
3. при передаче данных между клиентом и сервером через анализ трафика (сниффинг). Обычно такое возможно, только через HTTP.
См. также Принудительный HTTPS в ASP.NET Core.
Защитить файлы cookie можно с помощью флагов:
- HttpOnly – скрывает cookie от прямого доступа из кода JavaScript, что затрудняет межсайтовый скриптинг;
- secure – гарантирует, что cookie отправляется только через HTTPS.
Настройку флагов сеансовых файлов cookie нужно сделать явно в Program.cs:
Есть несколько признаков – но не доказательств! – успешной атаки:
1. Изменение IP-адреса.
Однако на это могут быть и законные причины: переключение мобильных устройств с Wi-Fi на мобильный интернет и обратно, балансировщики интернет-нагрузки в сети компании, автоматический сброс подключения через 24 часа у некоторых провайдеров и т.п.
2. Изменение других заголовков HTTP, например, строки user agent.
Это более весомый признак, хотя может случаться при обновлении браузера, поэтому сравнивать useк agent как строки посимвольно – не очень хорошая идея.
Требование повторного входа перед выполнением каких-либо критически важных операций может быть хорошей защитой от перехвата.
Источник: Кристиан Венц “Безопасность ASP.NET Core”. М.: ДМК Пресс, 2023. Глава 3.
Cookie и Управление Сессиями
Управление сессиями в ASP.NET Core зависит от файлов cookie. Сервер отправляет cookie с использованием HTTP-заголовка Set-Cookie, который содержит имя файла cookie, его значение и необязательные атрибуты, например дату истечения срока действия (по умолчанию cookie истекает при закрытии браузера). Браузер может принять, отклонить файл cookie или спросить пользователя, что делать. Почти всегда действует первый вариант. Отключение файлов cookie в браузере практически не позволяет использовать многие веб-приложения.
Поскольку cookie хранятся в браузере, их значениями легко манипулировать. Нельзя хранить конфиденциальную информацию в файле cookie, например текущее имя пользователя или его привилегии. Управление сессиями использует cookie, но снижает риски манипулирования данными. Сервер хранит уникальный идентификатор сессии, который отправляется клиенту в виде файла cookie. Идентификатор генерируется на сервере, он довольно длинный, и его практически невозможно угадать.
В ASP.NET Core функциональность сессий должна быть активирована явно. В Program.cs нужно вызвать
builder.Services.AddSession()
и app.UseSession()
.Браузер отправляет файлы cookie обратно на сервер с каждым последующим запросом, поэтому сервер всегда может идентифицировать сессию и получить доступ к правильным данным. Пока идентификатор сессии не будет украден, процесс безопасен. Но если злоумышленник получает идентификатор, он может выдать себя за пользователя при общении с сервером.
Злоумышленник может украсть идентификатор сессии 3 способами:
1. на стороне клиента, как правило, используя межсайтовый скриптинг;
2. на стороне сервера, но осуществить такую атаку довольно непросто;
3. при передаче данных между клиентом и сервером через анализ трафика (сниффинг). Обычно такое возможно, только через HTTP.
См. также Принудительный HTTPS в ASP.NET Core.
Защитить файлы cookie можно с помощью флагов:
- HttpOnly – скрывает cookie от прямого доступа из кода JavaScript, что затрудняет межсайтовый скриптинг;
- secure – гарантирует, что cookie отправляется только через HTTPS.
Настройку флагов сеансовых файлов cookie нужно сделать явно в Program.cs:
builder.Services.AddSession(opt => {Там же можно ограничить время, в течение которого можно использовать сеансовые cookie (по умолчанию 20 минут бездействия):
opt.Cookie.HttpOnly = true;
opt.Cookie.SecurePolicy =
CookieSecurePolicy.Always;
});
opt.IdleTimeout = TimeSpan.FromMinutes(5);Обнаружение перехвата сессии
Есть несколько признаков – но не доказательств! – успешной атаки:
1. Изменение IP-адреса.
Однако на это могут быть и законные причины: переключение мобильных устройств с Wi-Fi на мобильный интернет и обратно, балансировщики интернет-нагрузки в сети компании, автоматический сброс подключения через 24 часа у некоторых провайдеров и т.п.
2. Изменение других заголовков HTTP, например, строки user agent.
Это более весомый признак, хотя может случаться при обновлении браузера, поэтому сравнивать useк agent как строки посимвольно – не очень хорошая идея.
Требование повторного входа перед выполнением каких-либо критически важных операций может быть хорошей защитой от перехвата.
Источник: Кристиан Венц “Безопасность ASP.NET Core”. М.: ДМК Пресс, 2023. Глава 3.
👍17
День 1681. #ЧтоНовенького
Новинки ASP.NET Core в Превью 7 .NET 8
Последний превью выпуск .NET 8 содержит существенные дополнения и изменения в ASP.NET Core. Наиболее заметные улучшения связаны с Blazor, Native AOT, новыми шаблонами SPA в Visual Studio и промежуточным ПО защиты от поддельных запросов.
1. В Blazor конечные точки теперь должны по умолчанию использовать защиту от подделки (antiforgery). Начиная с этой версии компонент EditForm теперь автоматически добавляет токен защиты от подделки. Разработчики могут отключить его с помощью:
2. Для Minimal API было добавлено новое промежуточное ПО для проверки токенов защиты от подделки. Оно активируется при регистрации сервиса через AddAntiforgery. Обработчики запросов POST в минимальных API теперь будут автоматически проверять токен защиты от подделки. Если проверка токена завершается неудачей, в средах разработки будет выброшено исключение, в средах Production, будет добавляться запись в лог.
3. Автоматический интерактивный режим рендеринга в Blazor теперь сочетает в себе режимы рендеринга Server и WebAssembly. Этот режим оптимизирует рендеринг путём использования WebAssembly, если среда выполнения .NET загружается быстро (в течение 100 мс). Обычно это происходит в том случае, если среда выполнения была предварительно загружена и кэширована или используется высокоскоростная сеть. В противном случае используется серверный режим рендеринга, пока среда выполнения .NET WebAssembly загружается в фоновом режиме.
Чтобы использовать автоматической режим визуализации, укажите атрибут
4. Добавлен новый фабричный метод
-
-
-
5. Критическое изменение, затрагивающее веб-проекты, скомпилированные с включенным триммингом (
6. Представлены новые шаблоны Visual Studio для JavaScript и TypeScript разработки. Они включают шаблоны для Angular, React и Vue, используют новую систему проектов JavaScript (
Источники:
- https://www.infoq.com/news/2023/08/aspnet-core-8-preview-7/
- https://devblogs.microsoft.com/dotnet/asp-net-core-updates-in-dotnet-8-preview-7/
Новинки ASP.NET Core в Превью 7 .NET 8
Последний превью выпуск .NET 8 содержит существенные дополнения и изменения в ASP.NET Core. Наиболее заметные улучшения связаны с Blazor, Native AOT, новыми шаблонами SPA в Visual Studio и промежуточным ПО защиты от поддельных запросов.
1. В Blazor конечные точки теперь должны по умолчанию использовать защиту от подделки (antiforgery). Начиная с этой версии компонент EditForm теперь автоматически добавляет токен защиты от подделки. Разработчики могут отключить его с помощью:
@attribute [RequireAntiforgeryToken(required: false)]но делать так не рекомендуется.
2. Для Minimal API было добавлено новое промежуточное ПО для проверки токенов защиты от подделки. Оно активируется при регистрации сервиса через AddAntiforgery. Обработчики запросов POST в минимальных API теперь будут автоматически проверять токен защиты от подделки. Если проверка токена завершается неудачей, в средах разработки будет выброшено исключение, в средах Production, будет добавляться запись в лог.
3. Автоматический интерактивный режим рендеринга в Blazor теперь сочетает в себе режимы рендеринга Server и WebAssembly. Этот режим оптимизирует рендеринг путём использования WebAssembly, если среда выполнения .NET загружается быстро (в течение 100 мс). Обычно это происходит в том случае, если среда выполнения была предварительно загружена и кэширована или используется высокоскоростная сеть. В противном случае используется серверный режим рендеринга, пока среда выполнения .NET WebAssembly загружается в фоновом режиме.
Чтобы использовать автоматической режим визуализации, укажите атрибут
@rendermode="@RenderMode.Auto"
в экземпляре компонента или @attribute [RenderModeAuto]
в определении компонента. Обратите внимание, что компонент необходимо настроить для запуска как на сервере, так и в браузере, поэтому он должен находиться в клиентском проекте, и его реализация не должна быть привязана ни к серверу, ни к WebAssembly.4. Добавлен новый фабричный метод
WebApplication.CreateEmptyBuilder
, который позволяет создавать приложения наименьшего размера, содержащие только необходимые функции. Теперь доступно 3 варианта создания построителя приложения:-
CreateBuilder()
– полноценный построитель со всеми функциями;-
CreateSlimBuilder()
– построитель с минимальным набором функций (например, отсутствуют: поддержка IHostingStartup; поддержка UseStartup; поддержка провайдеров логов в логи событий Windows и в консоль отладки; поддержка интеграции с IIS; поддержка HTTPS; поддержка Regex в шаблонах маршрутов и т.п.);-
CreateEmptyBuilder()
– для поддержки минимальных приложений, который не будет содержать вообще никаких встроенных функций, только те, которые вы явно добавите.5. Критическое изменение, затрагивающее веб-проекты, скомпилированные с включенным триммингом (
PublishTrimmed=true
). Раньше в проектах по умолчанию использовался частичный режим тримминга (TrimMode=partial
). Однако, начиная с этого выпуска, все проекты, ориентированные на .NET 8 или более позднюю версию, по умолчанию будут использовать TrimMode=full
.6. Представлены новые шаблоны Visual Studio для JavaScript и TypeScript разработки. Они включают шаблоны для Angular, React и Vue, используют новую систему проектов JavaScript (
.esproj
) и легко интегрируются с серверными проектами ASP.NET Core.Источники:
- https://www.infoq.com/news/2023/08/aspnet-core-8-preview-7/
- https://devblogs.microsoft.com/dotnet/asp-net-core-updates-in-dotnet-8-preview-7/
👍6
День 1682. #Карьера
Как Общаться, Когда Доверие Низко (Не Закапывая Себя ещё Больше). Начало
Когда в отношениях мало доверия, вы склонны интерпретировать всё, что вам говорят, в худшем свете или слышать враждебность или пренебрежение там, где их нет. С другой стороны, трудно общаться, когда кажется, что всё, что вы говорите, неверно истолковывается или поворачивается против вас, независимо от того, насколько осторожными вы пытаетесь быть. Это может превратиться в смертельную спираль доверия, где каждое взаимодействие заканчивается тем, что каждый из вас немного больше ожесточается против собеседника и накапливает всё больше ран и обид.
Но чтобы работать вместе, НЕОБХОДИМО общаться! Вы должны иметь возможность спрашивать что-то и давать обратную связь. Доверие восстанавливается посредством маленьких позитивных взаимодействий. Если вы находитесь в «яме доверия», вы не сможете ясно услышать собеседника, а он не сможет ясно услышать вас (или ваши намерения). Поэтому придётся стараться сверхкоммуницировать и сверхкомпенсировать.
Существует множество книг о том, как говорить на сложные темы (например, «Трудные диалоги» Рона МакМиллана). Все они чертовски банальны, но прочитать хотя бы одну из них стоит. Вот коротко несколько тактик, которые могут сработать.
1. Заранее сообщите, что это трудно
«Мне есть что сказать, но я не знаю, как ты это воспримешь.»
Это заставит вас замедляться и внимательно выбирать слова, которые вы собираетесь использовать. А также даст собеседнику понять, что вам трудно это сказать, покажет, что вы заботитесь о его чувствах и стараетесь сделать для него всё возможное.
2. Либо признайтесь после
«Я не уверен, как я это донёс. Можно ли было бы это сформулировать лучше?»
Ничего страшного, если это произойдет через несколько минут, часов или дней; если это всё ещё вас гложет, объяснитесь.
3. Говорите осторожно
Очень полезно, когда отношения испортились, потому что вы явно допускаете, что у собеседника может быть другое восприятие, и выражаетесь безопасно, чтобы донести мысль.
«Мне кажется, что эти результаты могут быть неверны… вы видите то же самое?» - открывает дверь для дружеского разговора, основанного на конкретных результатах, тогда как фраза «Тут ошибка» может звучать обвинительно и вызывать защитную реакцию.
4. Старайтесь звучать дружелюбно
Чаще говорите «пожалуйста» и «спасибо», «привет», «лол» и т.п. Даже простое использование эмодзи в переписке сообщит о вашем настроении и смягчит реакцию собеседника. Это может показаться глупым, но это работает. Когда доверие низкое, отсутствие излишеств легко может быть воспринято как грубость.
5. Выдохните
Если вы испытываете паническую реакцию, сообщите, что вам нужно несколько минут, прежде чем ответить. Соберитесь с силами. Ответ, когда вы находитесь в режиме «сражайся или беги», почти всегда приводит к непреднамеренной эскалации. Если вам нужно несколько раз перечитать и осмыслить сообщение, найдите время. Но не молчите, сообщите, что вам нужна пара минут.
6. «В моей голове»
Если вы предполагаете худшее и считываете враждебные намерения в словах или действиях, постарайтесь проверить себя. Повторите собеседнику его слова вместе со своей интерпретацией, например: «В моей голове ваша просьба о статусе исполнения задачи выглядит как то, что вы не верите, что я выполняю работу». Это даст возможность ответить и уточнить, что собеседник на самом деле имел в виду.
7. Ищите позитивные коммуникации даже через силу
Эксперты по взаимоотношениям говорят, что в счастливых и здоровых отношениях на каждое негативное взаимодействие приходится как минимум пять положительных. Если у вас натянутые отношения с кем-то, вы общаетесь с ним только тогда, когда вам приходится это делать. И вы всегда будете этого бояться. Это может показаться искусственным, но ищите возможности для любого позитивного взаимодействия и используйте их.
Окончание следует…
Источник: https://charity.wtf/2023/08/17/how-to-communicate-when-trust-is-low-without-digging-yourself-into-a-deeper-hole/
Как Общаться, Когда Доверие Низко (Не Закапывая Себя ещё Больше). Начало
Когда в отношениях мало доверия, вы склонны интерпретировать всё, что вам говорят, в худшем свете или слышать враждебность или пренебрежение там, где их нет. С другой стороны, трудно общаться, когда кажется, что всё, что вы говорите, неверно истолковывается или поворачивается против вас, независимо от того, насколько осторожными вы пытаетесь быть. Это может превратиться в смертельную спираль доверия, где каждое взаимодействие заканчивается тем, что каждый из вас немного больше ожесточается против собеседника и накапливает всё больше ран и обид.
Но чтобы работать вместе, НЕОБХОДИМО общаться! Вы должны иметь возможность спрашивать что-то и давать обратную связь. Доверие восстанавливается посредством маленьких позитивных взаимодействий. Если вы находитесь в «яме доверия», вы не сможете ясно услышать собеседника, а он не сможет ясно услышать вас (или ваши намерения). Поэтому придётся стараться сверхкоммуницировать и сверхкомпенсировать.
Существует множество книг о том, как говорить на сложные темы (например, «Трудные диалоги» Рона МакМиллана). Все они чертовски банальны, но прочитать хотя бы одну из них стоит. Вот коротко несколько тактик, которые могут сработать.
1. Заранее сообщите, что это трудно
«Мне есть что сказать, но я не знаю, как ты это воспримешь.»
Это заставит вас замедляться и внимательно выбирать слова, которые вы собираетесь использовать. А также даст собеседнику понять, что вам трудно это сказать, покажет, что вы заботитесь о его чувствах и стараетесь сделать для него всё возможное.
2. Либо признайтесь после
«Я не уверен, как я это донёс. Можно ли было бы это сформулировать лучше?»
Ничего страшного, если это произойдет через несколько минут, часов или дней; если это всё ещё вас гложет, объяснитесь.
3. Говорите осторожно
Очень полезно, когда отношения испортились, потому что вы явно допускаете, что у собеседника может быть другое восприятие, и выражаетесь безопасно, чтобы донести мысль.
«Мне кажется, что эти результаты могут быть неверны… вы видите то же самое?» - открывает дверь для дружеского разговора, основанного на конкретных результатах, тогда как фраза «Тут ошибка» может звучать обвинительно и вызывать защитную реакцию.
4. Старайтесь звучать дружелюбно
Чаще говорите «пожалуйста» и «спасибо», «привет», «лол» и т.п. Даже простое использование эмодзи в переписке сообщит о вашем настроении и смягчит реакцию собеседника. Это может показаться глупым, но это работает. Когда доверие низкое, отсутствие излишеств легко может быть воспринято как грубость.
5. Выдохните
Если вы испытываете паническую реакцию, сообщите, что вам нужно несколько минут, прежде чем ответить. Соберитесь с силами. Ответ, когда вы находитесь в режиме «сражайся или беги», почти всегда приводит к непреднамеренной эскалации. Если вам нужно несколько раз перечитать и осмыслить сообщение, найдите время. Но не молчите, сообщите, что вам нужна пара минут.
6. «В моей голове»
Если вы предполагаете худшее и считываете враждебные намерения в словах или действиях, постарайтесь проверить себя. Повторите собеседнику его слова вместе со своей интерпретацией, например: «В моей голове ваша просьба о статусе исполнения задачи выглядит как то, что вы не верите, что я выполняю работу». Это даст возможность ответить и уточнить, что собеседник на самом деле имел в виду.
7. Ищите позитивные коммуникации даже через силу
Эксперты по взаимоотношениям говорят, что в счастливых и здоровых отношениях на каждое негативное взаимодействие приходится как минимум пять положительных. Если у вас натянутые отношения с кем-то, вы общаетесь с ним только тогда, когда вам приходится это делать. И вы всегда будете этого бояться. Это может показаться искусственным, но ищите возможности для любого позитивного взаимодействия и используйте их.
Окончание следует…
Источник: https://charity.wtf/2023/08/17/how-to-communicate-when-trust-is-low-without-digging-yourself-into-a-deeper-hole/
👍14
День 1683. #Карьера
Как Общаться, Когда Доверие Низко (Не Закапывая Себя ещё Больше). Окончание
Начало
8. Сообщайте позитивные намерения
В среде с низким уровнем доверия вы можете предположить, что всё, что вы говорите, будет прочитано угрожающим, пренебрежительным или насмешливым тоном. Вам следует обратить особое внимание на тон и голос, а также добавить дополнительные слова, которые передадут нужный вам посыл. Нейтральное утверждение типа «Это число выглядит неправильным» или «Почему этот показатель не растёт?» прозвучит резко и обвинительно. Например: показатель не растет, это твоя вина, ты должен это знать, я виню тебя, ты плохо делаешь свою работу. Не «может прозвучать», а «именно так и прозвучит». Постарайтесь защитить свой посыл от искажений, сказав что-то вроде:
«Эй, я знаю, что ты только что работал с этим, тебе не кажется, что это число неверное?»
«Этот показатель кажется ниже, чем обычно. Мне интересно, связано ли это с другой вещью, которую мы пробовали. Или у тебя есть идеи получше?»
«Я знаю, что это не совсем в твоей сфере, но можешь ли ты помочь мне это понять?»
Это может показаться чрезмерным и отнимающим много времени, но в итоге это сэкономит время и усилия, поскольку у вас накопится меньше недопониманий для отладки.
9. Дайте людям возможность сформулировать лучше
Мы склонны очень быстро формировать мнение о людях и с этого момента смотреть на них через эту призму. Требуется работа, чтобы изменить мнение о человеке.
«Всегда предполагать позитивное намерение» — хорошая цель, но на практике она не соответствует действительности. Если каждое сказанное кем-то слово звучит для вас обвинительно или покровительственно, что делать с этим советом? Просто притвориться, что не слышите, или сказать себе, что они подразумевают добрые намерения? Это неустойчиво; ваш гнев и сомнения будут только нарастать. Но можно удержать мысль о том, что собеседник имеет добрые намерения, и дать ему возможность уточнить (и, возможно, в следующий раз использовать другие слова). Например,
А: «Почему этот показатель такой низкий?»
Б: «Я не уверен».
(Пауза)
Б: «…. Эй, извини, что прерываю, но мне показалось, что ты думаешь, что я отвечаю за этот показатель, а теперь ты расстроен из-за меня или думаешь, что я некомпетентен в своей работе».
А: «Вовсе нет. Я просто пытаюсь выяснить, кто разбирается в этой части системы, поскольку, похоже, никто из этого не понимает! Извини, что заставил нервничать!»
и, возможно, в следующий раз всё начнётся так…
А: «Привет, ты не в курсе, почему этот показатель такой низкий? А то кажется, никто из тех, с кем я разговаривал, не знает».
10. Цените усилия
Вы когда-нибудь встречали в онлайне кого-то, кто вам не понравился, а при личной встрече понимали, что он прекрасный человек? Онлайн-общение очень много теряет «при транспортировке». Если вы в большинстве случаев общаетесь с кем-то в чате, обсуждайте самые спорные темы «ртом», по телефону или видеосвязи. Это не так хорошо, как личное общение, но гораздо лучше, чем текст.
После того, как вы встретились с кем-то лично, обычно легче прочитать написанные слова его голосом. Некоторые люди просто не очень хороши в письменном общении. Возможно, ваш язык общения – не родной для собеседника. И так далее. Ставьте собеседнику плюсики за усилия. Если он пытается донести мысль дружелюбно, очевидно, для него важно, как вы это воспримете.
В меру своих возможностей старайтесь не читать (и не писать) «между строк» в текстовом общении. Будьте проще, передавайте намерения явно и просите ясности от собеседника. А если кто-то просит вас внести ясность, помогите ему, и это сработает на вас.
Источник: https://charity.wtf/2023/08/17/how-to-communicate-when-trust-is-low-without-digging-yourself-into-a-deeper-hole/
Как Общаться, Когда Доверие Низко (Не Закапывая Себя ещё Больше). Окончание
Начало
8. Сообщайте позитивные намерения
В среде с низким уровнем доверия вы можете предположить, что всё, что вы говорите, будет прочитано угрожающим, пренебрежительным или насмешливым тоном. Вам следует обратить особое внимание на тон и голос, а также добавить дополнительные слова, которые передадут нужный вам посыл. Нейтральное утверждение типа «Это число выглядит неправильным» или «Почему этот показатель не растёт?» прозвучит резко и обвинительно. Например: показатель не растет, это твоя вина, ты должен это знать, я виню тебя, ты плохо делаешь свою работу. Не «может прозвучать», а «именно так и прозвучит». Постарайтесь защитить свой посыл от искажений, сказав что-то вроде:
«Эй, я знаю, что ты только что работал с этим, тебе не кажется, что это число неверное?»
«Этот показатель кажется ниже, чем обычно. Мне интересно, связано ли это с другой вещью, которую мы пробовали. Или у тебя есть идеи получше?»
«Я знаю, что это не совсем в твоей сфере, но можешь ли ты помочь мне это понять?»
Это может показаться чрезмерным и отнимающим много времени, но в итоге это сэкономит время и усилия, поскольку у вас накопится меньше недопониманий для отладки.
9. Дайте людям возможность сформулировать лучше
Мы склонны очень быстро формировать мнение о людях и с этого момента смотреть на них через эту призму. Требуется работа, чтобы изменить мнение о человеке.
«Всегда предполагать позитивное намерение» — хорошая цель, но на практике она не соответствует действительности. Если каждое сказанное кем-то слово звучит для вас обвинительно или покровительственно, что делать с этим советом? Просто притвориться, что не слышите, или сказать себе, что они подразумевают добрые намерения? Это неустойчиво; ваш гнев и сомнения будут только нарастать. Но можно удержать мысль о том, что собеседник имеет добрые намерения, и дать ему возможность уточнить (и, возможно, в следующий раз использовать другие слова). Например,
А: «Почему этот показатель такой низкий?»
Б: «Я не уверен».
(Пауза)
Б: «…. Эй, извини, что прерываю, но мне показалось, что ты думаешь, что я отвечаю за этот показатель, а теперь ты расстроен из-за меня или думаешь, что я некомпетентен в своей работе».
А: «Вовсе нет. Я просто пытаюсь выяснить, кто разбирается в этой части системы, поскольку, похоже, никто из этого не понимает! Извини, что заставил нервничать!»
и, возможно, в следующий раз всё начнётся так…
А: «Привет, ты не в курсе, почему этот показатель такой низкий? А то кажется, никто из тех, с кем я разговаривал, не знает».
10. Цените усилия
Вы когда-нибудь встречали в онлайне кого-то, кто вам не понравился, а при личной встрече понимали, что он прекрасный человек? Онлайн-общение очень много теряет «при транспортировке». Если вы в большинстве случаев общаетесь с кем-то в чате, обсуждайте самые спорные темы «ртом», по телефону или видеосвязи. Это не так хорошо, как личное общение, но гораздо лучше, чем текст.
После того, как вы встретились с кем-то лично, обычно легче прочитать написанные слова его голосом. Некоторые люди просто не очень хороши в письменном общении. Возможно, ваш язык общения – не родной для собеседника. И так далее. Ставьте собеседнику плюсики за усилия. Если он пытается донести мысль дружелюбно, очевидно, для него важно, как вы это воспримете.
В меру своих возможностей старайтесь не читать (и не писать) «между строк» в текстовом общении. Будьте проще, передавайте намерения явно и просите ясности от собеседника. А если кто-то просит вас внести ясность, помогите ему, и это сработает на вас.
Источник: https://charity.wtf/2023/08/17/how-to-communicate-when-trust-is-low-without-digging-yourself-into-a-deeper-hole/
👍5
День 1684. #PostgresTips
Советы по Postgres для Начинающих
9. Оптимизация запросов или настройки конфигурации
Когда дело касается производительности, в большинстве случаев полезно оптимизировать конфигурацию Postgres «достаточно хорошо», изредка пересматривая решения (например, после серьёзного обновления Postgres), а затем полностью сосредоточиться на настройке запросов. Особенно, если вы часто меняете приложение.
Первоначальная настройка конфигурации может привести к повышению производительности. Но по мере роста и развития приложения основная борьба за производительность часто смещается к оптимизации запросов. Среди новичков распространено заблуждение: «Если я хорошо настрою конфигурацию, у меня не будет проблем». Настройка конфигурации жизненно важна, но это только начало. В конце концов, придётся сосредоточиться на постоянной оптимизации запросов.
Уже обсуждавшийся pg_stat_statements — бесценный инструмент для выявления проблемных запросов. Он предоставляет ранжированный список операторов SQL, упорядоченный по различным показателям. В сочетании с EXPLAIN (ANALYZE, BUFFERS), вы можете понять план выполнения запроса и выявить неэффективность.
10. Ведение индекса: необходимая практика
Индексы имеют решающее значение для производительности любой реляционной БД, и Postgres не является исключением. Со временем, по мере изменения данных, индексы становятся фрагментированными и менее эффективными. Даже при использовании современных версий Postgres и хорошо настроенной автоочистке работоспособность индекса по-прежнему ухудшается с течением времени, по мере того как происходят многочисленные записи.
Когда данные вставляются, обновляются или удаляются, индексы, отражающие эти данные, претерпевают изменения. Эти изменения могут привести к тому, что структура индекса станет несбалансированной или появится неработающие записи, что замедлит производительность поиска.
Индексы не сохраняют свою оптимальную структуру бесконечно. Периодически их необходимо восстанавливать (REINDEX). Этот процесс включает в себя создание новой версии индекса, что часто приводит к более компактной и эффективной структуре. Настройка таких восстановлений, желательно в автоматическом режиме, гарантирует постоянство производительности БД.
Не менее важно удалять неиспользуемые или избыточные индексы. Они не только тратят место, но и могут замедлять операции записи. Регулярная проверка и очистка ненужных индексов должны быть частью вашей процедуры обслуживания.
Бонус: документация Postgres - ваш надёжный спутник
Всегда имейте в закладках официальную документацию Postgres:
- Она всеобъемлюща и актуальна: является наиболее авторитетным источником информации, подробно описывающим каждую функцию, поведение и нюансы Postgres.
- Содержит примечания к релизу с кратким описанием всех изменений, новых функций и улучшений. Это отличный способ быть в курсе того, что нового появилось и что может повлиять на ваши существующие настройки.
- Комментарии к исходному коду/файлы README: для тех, кто любит глубоко погружаться, исходный код Postgres — это не только учебный ресурс, но и справочный материал. Они могут дать ценную информацию и объяснения, которые могут быть неочевидны в других источниках.
Источник: https://postgres.ai/blog/20230722-10-postgres-tips-for-beginners
Советы по Postgres для Начинающих
9. Оптимизация запросов или настройки конфигурации
Когда дело касается производительности, в большинстве случаев полезно оптимизировать конфигурацию Postgres «достаточно хорошо», изредка пересматривая решения (например, после серьёзного обновления Postgres), а затем полностью сосредоточиться на настройке запросов. Особенно, если вы часто меняете приложение.
Первоначальная настройка конфигурации может привести к повышению производительности. Но по мере роста и развития приложения основная борьба за производительность часто смещается к оптимизации запросов. Среди новичков распространено заблуждение: «Если я хорошо настрою конфигурацию, у меня не будет проблем». Настройка конфигурации жизненно важна, но это только начало. В конце концов, придётся сосредоточиться на постоянной оптимизации запросов.
Уже обсуждавшийся pg_stat_statements — бесценный инструмент для выявления проблемных запросов. Он предоставляет ранжированный список операторов SQL, упорядоченный по различным показателям. В сочетании с EXPLAIN (ANALYZE, BUFFERS), вы можете понять план выполнения запроса и выявить неэффективность.
10. Ведение индекса: необходимая практика
Индексы имеют решающее значение для производительности любой реляционной БД, и Postgres не является исключением. Со временем, по мере изменения данных, индексы становятся фрагментированными и менее эффективными. Даже при использовании современных версий Postgres и хорошо настроенной автоочистке работоспособность индекса по-прежнему ухудшается с течением времени, по мере того как происходят многочисленные записи.
Когда данные вставляются, обновляются или удаляются, индексы, отражающие эти данные, претерпевают изменения. Эти изменения могут привести к тому, что структура индекса станет несбалансированной или появится неработающие записи, что замедлит производительность поиска.
Индексы не сохраняют свою оптимальную структуру бесконечно. Периодически их необходимо восстанавливать (REINDEX). Этот процесс включает в себя создание новой версии индекса, что часто приводит к более компактной и эффективной структуре. Настройка таких восстановлений, желательно в автоматическом режиме, гарантирует постоянство производительности БД.
Не менее важно удалять неиспользуемые или избыточные индексы. Они не только тратят место, но и могут замедлять операции записи. Регулярная проверка и очистка ненужных индексов должны быть частью вашей процедуры обслуживания.
Бонус: документация Postgres - ваш надёжный спутник
Всегда имейте в закладках официальную документацию Postgres:
- Она всеобъемлюща и актуальна: является наиболее авторитетным источником информации, подробно описывающим каждую функцию, поведение и нюансы Postgres.
- Содержит примечания к релизу с кратким описанием всех изменений, новых функций и улучшений. Это отличный способ быть в курсе того, что нового появилось и что может повлиять на ваши существующие настройки.
- Комментарии к исходному коду/файлы README: для тех, кто любит глубоко погружаться, исходный код Postgres — это не только учебный ресурс, но и справочный материал. Они могут дать ценную информацию и объяснения, которые могут быть неочевидны в других источниках.
Источник: https://postgres.ai/blog/20230722-10-postgres-tips-for-beginners
👍4
День 1685. #ЗаметкиНаПолях
Решение Проблем Гонки с Помощью Оптимистической Блокировки EF Core. Начало
Как часто вы думаете о конфликтах параллелизма при написании кода? Вы пишете код новой функции, проверяете, что она работает, и всё. Но неделю спустя вы обнаруживаете, что допустили неприятную ошибку, потому что не подумали о параллелизме. Наиболее распространённой проблемой являются условия гонки, когда два конкурирующих потока выполняют одну и ту же функцию. Если вы не учтёте это во время разработки, вы рискуете оставить систему в повреждённом состоянии.
Рассмотрим пример.
Бизнес-требование: нельзя иметь два перекрывающихся бронирования на одни и те же даты. В следующем примере кода скрывается проблема состояния гонки:
Проблема в том, что существует вероятность того, что параллельный запрос пройдёт проверку IsOverlapping и попытается сделать бронирование. Без какого-либо контроля параллелизма оба запроса будут успешными, и в итоге мы получим несогласованное состояние БД.
При пессимистическом подходе обработки параллелизма данные в БД блокируются между чтением и изменением. Это медленно и приводит к блокировке конкурирующих транзакций до тех пор, пока блокировка не будет снята. EF Core не поддерживает этот подход «из коробки». Оптимистический параллелизм в EF Core не требует блокировок, но любые изменения данных не будут сохранены, если данные изменились с момента чтения.
Чтобы реализовать оптимистичный параллелизм в EF Core, необходимо настроить свойство как токен параллелизма. Оно загружается и отслеживается вместе с сущностью. Когда вы вызываете SaveChanges, EF Core сравнивает значение токена параллелизма со значением в базе данных.
Например, в SQL Server есть столбец rowversion, который автоматически меняется при обновлении строки, поэтому это отличный вариант для токена параллелизма. Можно настроить теневое свойство в EF Core, чтобы спрятать его от основного класса сущности:
При загрузке сущности Apart EF также загрузит токен параллелизма.
Окончание следует…
Источник: https://www.milanjovanovic.tech/blog/solving-race-conditions-with-ef-core-optimistic-locking
Решение Проблем Гонки с Помощью Оптимистической Блокировки EF Core. Начало
Как часто вы думаете о конфликтах параллелизма при написании кода? Вы пишете код новой функции, проверяете, что она работает, и всё. Но неделю спустя вы обнаруживаете, что допустили неприятную ошибку, потому что не подумали о параллелизме. Наиболее распространённой проблемой являются условия гонки, когда два конкурирующих потока выполняют одну и ту же функцию. Если вы не учтёте это во время разработки, вы рискуете оставить систему в повреждённом состоянии.
Рассмотрим пример.
Бизнес-требование: нельзя иметь два перекрывающихся бронирования на одни и те же даты. В следующем примере кода скрывается проблема состояния гонки:
public Result<Guid> Handle(Вызов IsOverlapping — это оптимистичная проверка, существует ли бронирование на указанные даты. Если ответ true, это попытка конкурентного бронирования на те же даты, поэтому мы возвращаем ошибку. Но если возвращается false, мы бронируем и вызываем SaveChanges, чтобы сохранить изменения в БД.
ReserveBooking command,
AppDbContext ctx)
{
var user = ctx.Users.GetById(command.UserId);
var apart = ctx.Aparts.GetById(command.ApartId);
var (start, end) = command;
if (dbContext.Bookings
.IsOverlapping(apart, start, end))
return Result.Failure<Guid>(Errors.Overlap);
var booking = Booking
.Reserve(apart, user, start, end);
ctx.Add(booking);
ctx.SaveChanges();
return booking.Id;
}
Проблема в том, что существует вероятность того, что параллельный запрос пройдёт проверку IsOverlapping и попытается сделать бронирование. Без какого-либо контроля параллелизма оба запроса будут успешными, и в итоге мы получим несогласованное состояние БД.
При пессимистическом подходе обработки параллелизма данные в БД блокируются между чтением и изменением. Это медленно и приводит к блокировке конкурирующих транзакций до тех пор, пока блокировка не будет снята. EF Core не поддерживает этот подход «из коробки». Оптимистический параллелизм в EF Core не требует блокировок, но любые изменения данных не будут сохранены, если данные изменились с момента чтения.
Чтобы реализовать оптимистичный параллелизм в EF Core, необходимо настроить свойство как токен параллелизма. Оно загружается и отслеживается вместе с сущностью. Когда вы вызываете SaveChanges, EF Core сравнивает значение токена параллелизма со значением в базе данных.
Например, в SQL Server есть столбец rowversion, который автоматически меняется при обновлении строки, поэтому это отличный вариант для токена параллелизма. Можно настроить теневое свойство в EF Core, чтобы спрятать его от основного класса сущности:
protected override void OnModelCreating(* Точная конфигурация будет зависеть от типа вашей БД.
ModelBuilder mb)
{
mb.Entity<Apart>()
.Property<byte[]>("Version")
.IsRowVersion();
}
При загрузке сущности Apart EF также загрузит токен параллелизма.
SELECT a.Id, a.VersionА при вызове SaveChanges, запрос UPDATE сравнит его с текущим токеном в БД:
FROM Aparts a
WHERE a.Id = @p0
UPDATE Aparts aЕсли версия в базе отличается, будет обновлено 0 строк, а EF Core ожидает обновления 1 строки, поэтому будет выброшено исключение DbUpdateConcurrencyException, которое надо обработать.
SET a.LastBookedOnUtc = @p0
WHERE a.Id = @p1 AND a.Version = @p2;
Окончание следует…
Источник: https://www.milanjovanovic.tech/blog/solving-race-conditions-with-ef-core-optimistic-locking
👍22