This media is not supported in your browser
VIEW IN TELEGRAM
День четыреста двадцать пятый. #ЧтоНовенького
VS 2019 16.6 Preview 2. Начало
Visual Studio 2019 версии 16.6 Preview 2 предоставляет несколько новых интересных возможностей, которые вы можете попробовать уже сегодня.
1. Модернизирована функциональность Git. Вы можете начать работу с кодом, просматривая онлайн-репозитории GitHub или Azure в Visual Studio и клонируя их локально. Для новых проектов вы можете инициализировать Git-репозиторий и поместить его в GitHub одним щелчком мыши. Новое окно инструмента Git объединяет все операции Git, связанные с вашим кодом.
Функция упрощает сложную навигацию для Git, которая использовалась в Team Explorer. Новое окно минимизирует переключение контекста между инструментами и приложениями, и вы можете быстро выполнять нужные операции. Также появилось новое меню Git на замену старому Teams.
Если вы хотите попробовать новый инструмент скачайте превью версию, перейдите в Tools > Options и включите функцию New Git user experience в разделе Preview Features.
Источник
VS 2019 16.6 Preview 2. Начало
Visual Studio 2019 версии 16.6 Preview 2 предоставляет несколько новых интересных возможностей, которые вы можете попробовать уже сегодня.
1. Модернизирована функциональность Git. Вы можете начать работу с кодом, просматривая онлайн-репозитории GitHub или Azure в Visual Studio и клонируя их локально. Для новых проектов вы можете инициализировать Git-репозиторий и поместить его в GitHub одним щелчком мыши. Новое окно инструмента Git объединяет все операции Git, связанные с вашим кодом.
Функция упрощает сложную навигацию для Git, которая использовалась в Team Explorer. Новое окно минимизирует переключение контекста между инструментами и приложениями, и вы можете быстро выполнять нужные операции. Также появилось новое меню Git на замену старому Teams.
Если вы хотите попробовать новый инструмент скачайте превью версию, перейдите в Tools > Options и включите функцию New Git user experience в разделе Preview Features.
Источник
День четыреста двадцать шестой. #АтакиНаСайты
ASP.NET MVC 5. Безопасность Веб-Приложений
5. Открытое перенаправление
Любое веб-приложение, которое перенаправляет на URL-адрес, указанный в запросе, например, в строке запроса или в данных формы, потенциально может быть атаковано для перенаправления пользователей на внешний вредоносный URL-адрес. Это называется атакой с открытым перенаправлением. Всякий раз, когда логика вашего приложения перенаправляет на указанный URL-адрес, вы должны убедиться, что URL-адрес перенаправления не был подделан.
Простая атака с открытым перенаправлением
Рассмотрим пример. В веб-приложении при попытке посетить действие контроллера, помеченное атрибутом
Более сложная атака включает элементы фишинга. Подобная атака была проведена на сайт NerdDinner (после этого уязвимость на сайте была исправлена). Сначала злоумышленник отправляет ссылку на страницу входа в NerdDinner, которая включает перенаправление на поддельную страницу:
Вы, скорее всего, не заметите этого, особенно потому, что злоумышленник убедился, чтобы его поддельная страница выглядела точно так же, как и страница настоящего сайта. Поддельная страница входа содержит сообщение о неправильном пароле. Пользователь ничего не подозревает и вводит логин и пароль повторно. Поддельная страница сохраняет эту информацию и отправляет вас обратно на настоящий сайт NerdDinner.com. На данный момент сайт NerdDinner.com уже аутентифицировал вас, поэтому поддельная страница входа в систему может безопасно перенаправлять туда. В итоге у злоумышленника есть ваши логин и пароль, а вы даже не знаете, что предоставили их ему.
Предотвращение атаки с открытым перенаправлением
Проверка адреса перенаправления предотвращает такую атаку. В ASP.NET Core также можно использовать действие
Источник: Jon Galloway “Professional ASP.NET MVC 5”. – John Wiley & Sons Inc., 2014. Глава 7.
ASP.NET MVC 5. Безопасность Веб-Приложений
5. Открытое перенаправление
Любое веб-приложение, которое перенаправляет на URL-адрес, указанный в запросе, например, в строке запроса или в данных формы, потенциально может быть атаковано для перенаправления пользователей на внешний вредоносный URL-адрес. Это называется атакой с открытым перенаправлением. Всякий раз, когда логика вашего приложения перенаправляет на указанный URL-адрес, вы должны убедиться, что URL-адрес перенаправления не был подделан.
Простая атака с открытым перенаправлением
Рассмотрим пример. В веб-приложении при попытке посетить действие контроллера, помеченное атрибутом
AuthorizeAttribute
, неавторизованный пользователь попадает в представление /Account/LogOn
. Это перенаправление на включает параметр строки запроса returnUrl
, чтобы пользователи могли вернуться на первоначально запрошенный URL после успешного входа в систему. Поскольку этот параметр не проверяется, злоумышленник может изменить его на любой URL-адрес для проведения атаки с открытым перенаправлением.Более сложная атака включает элементы фишинга. Подобная атака была проведена на сайт NerdDinner (после этого уязвимость на сайте была исправлена). Сначала злоумышленник отправляет ссылку на страницу входа в NerdDinner, которая включает перенаправление на поддельную страницу:
https://nerddinner.com/Account/LogOn?returnUrl=https://nerddiner.com/Account/LogOnОбратите внимание, что обратный URL-адрес указывает на поддельный сайт nerddiner.com, в котором одна «n». Этот домен контролирует злоумышленник. Когда вы проходите по ссылке, вы попадаете на обычную страницу входа на NerdDinner.com. При успешном входе в систему действие
LogOn
перенаправляет вас на URL-адрес, указанный в параметре строки запроса returnUrl
. В данном случае это введённый злоумышленником URL:https://nerddiner.com/Account/LogOn
. Вы, скорее всего, не заметите этого, особенно потому, что злоумышленник убедился, чтобы его поддельная страница выглядела точно так же, как и страница настоящего сайта. Поддельная страница входа содержит сообщение о неправильном пароле. Пользователь ничего не подозревает и вводит логин и пароль повторно. Поддельная страница сохраняет эту информацию и отправляет вас обратно на настоящий сайт NerdDinner.com. На данный момент сайт NerdDinner.com уже аутентифицировал вас, поэтому поддельная страница входа в систему может безопасно перенаправлять туда. В итоге у злоумышленника есть ваши логин и пароль, а вы даже не знаете, что предоставили их ему.
Предотвращение атаки с открытым перенаправлением
Проверка адреса перенаправления предотвращает такую атаку. В ASP.NET Core также можно использовать действие
LocalRedirect
. Но, возможно, вы захотите предпринять дополнительные действия при обнаружении открытого перенаправления. Тогда можно проверять адрес перенаправления с помощью метода расширения Url.IsLocalUrl(returnUrl)
, возвращающего bool
. И если адрес не является локальным, например, регистрировать это как исключение безопасности и отображать пользователю сообщение, что ссылка, которую они использовали, могла быть вредоносной.Источник: Jon Galloway “Professional ASP.NET MVC 5”. – John Wiley & Sons Inc., 2014. Глава 7.
День четыреста двадцать седьмой. #ЧтоНовенького
VS 2019 16.6 Preview 2. Продолжение
Visual Studio 2019 версии 16.6 Preview 2 предоставляет несколько новых интересных возможностей, которые вы можете попробовать уже сегодня.
Первая часть
2. Новый инструмент .NET Async
Новый инструмент является частью набора инструментов Performance Profiler. Это упрощает понимание и оптимизацию async/await кода в .NET. По сути, вы можете использовать его для получения точной информации о сроках выполнения различных задач, включая то, сколько времени они ожидали отправки в поток, сколько времени потребовалось для завершения и были ли задачи объединены в цепочку.
4. Новые возможности отладки JavaScript/TypeScript
Отладчик JavaScript/TypeScript теперь поддерживает отладку service worker’ов, web worker’ов, iFrame’ов и кода JavaScript вашей страницы одновременно. Кроме того, теперь поддерживается отладка серверных и клиентских приложений JavaScript одновременно.
5. Построитель Моделей ML.NET
С помощью ML.NET Model Builder вы можете легко создавать и использовать пользовательские модели машинного обучения для классификации текста, прогнозирования значений, рекомендаций и классификации изображений в своих приложениях .NET. Всё, что вам нужно сделать, это выбрать сценарий машинного обучения и набор данных. Model Builder позаботится об обучении моделей, выборе наилучшей модели для ваших данных и создании кода .NET для использования модели в вашем приложении. Вы даже можете масштабироваться до облака и использовать возможности машинного обучения Azure для моделей классификации изображений, не выходя из Visual Studio или .NET.
6. Обновления процесса публикации
Теперь предлагается новый процесс в виде мастера для создания новых профилей публикации. Этот инструмент проведёт вас через различные варианты. Даже если некоторые компоненты Visual Studio отсутствуют в вашей установке, вы всё равно будете иметь доступ к полному набору целей и параметров публикации. Следовательно, любые недостающие компоненты будут идентифицированы и запрошены для установки по требованию. Сводная страница профиля публикации также была обновлена в соответствии с новыми возможностями, доступными на вкладке Connected Services для настройки зависимостей для служб Azure.
Источник: https://devblogs.microsoft.com/visualstudio/visual-studio-2019-version-16-6-preview-2/
VS 2019 16.6 Preview 2. Продолжение
Visual Studio 2019 версии 16.6 Preview 2 предоставляет несколько новых интересных возможностей, которые вы можете попробовать уже сегодня.
Первая часть
2. Новый инструмент .NET Async
Новый инструмент является частью набора инструментов Performance Profiler. Это упрощает понимание и оптимизацию async/await кода в .NET. По сути, вы можете использовать его для получения точной информации о сроках выполнения различных задач, включая то, сколько времени они ожидали отправки в поток, сколько времени потребовалось для завершения и были ли задачи объединены в цепочку.
4. Новые возможности отладки JavaScript/TypeScript
Отладчик JavaScript/TypeScript теперь поддерживает отладку service worker’ов, web worker’ов, iFrame’ов и кода JavaScript вашей страницы одновременно. Кроме того, теперь поддерживается отладка серверных и клиентских приложений JavaScript одновременно.
5. Построитель Моделей ML.NET
С помощью ML.NET Model Builder вы можете легко создавать и использовать пользовательские модели машинного обучения для классификации текста, прогнозирования значений, рекомендаций и классификации изображений в своих приложениях .NET. Всё, что вам нужно сделать, это выбрать сценарий машинного обучения и набор данных. Model Builder позаботится об обучении моделей, выборе наилучшей модели для ваших данных и создании кода .NET для использования модели в вашем приложении. Вы даже можете масштабироваться до облака и использовать возможности машинного обучения Azure для моделей классификации изображений, не выходя из Visual Studio или .NET.
6. Обновления процесса публикации
Теперь предлагается новый процесс в виде мастера для создания новых профилей публикации. Этот инструмент проведёт вас через различные варианты. Даже если некоторые компоненты Visual Studio отсутствуют в вашей установке, вы всё равно будете иметь доступ к полному набору целей и параметров публикации. Следовательно, любые недостающие компоненты будут идентифицированы и запрошены для установки по требованию. Сводная страница профиля публикации также была обновлена в соответствии с новыми возможностями, доступными на вкладке Connected Services для настройки зависимостей для служб Azure.
Источник: https://devblogs.microsoft.com/visualstudio/visual-studio-2019-version-16-6-preview-2/
День четыреста двадцать восьмой. #ЧтоНовенького
VS 2019 16.6 Preview 2. Окончание
Visual Studio 2019 версии 16.6 Preview 2 предоставляет несколько новых интересных возможностей, которые вы можете попробовать уже сегодня.
Первая часть | Вторая часть
7. Продуктивность в .NET
Добавлено несколько новых возможностей в меню Quick Actions and Refactorings, доступному через
2. Возможность автоматически генерировать заголовочные комментарии для существующих файлов, проектов и решений с помощью EditorConfig. Вы можете добавить правило
3. Теперь вы можете упростить условные выражения, удалив ненужный код, используя новую возможность Simplify conditional expression (см. картинку 4 ниже).
4. Кроме того, появилась новая опция Convert verbatim string, которая позволяет преобразовывать обычные строковые литералы в дословные и обратно (см. картинку 5 ниже).
Источник: https://devblogs.microsoft.com/visualstudio/visual-studio-2019-version-16-6-preview-2/
VS 2019 16.6 Preview 2. Окончание
Visual Studio 2019 версии 16.6 Preview 2 предоставляет несколько новых интересных возможностей, которые вы можете попробовать уже сегодня.
Первая часть | Вторая часть
7. Продуктивность в .NET
Добавлено несколько новых возможностей в меню Quick Actions and Refactorings, доступному через
Ctrl+.
1. Явное приведение, когда выражение не может быть приведено явным образом. Выберите пункт меню Add explicit cast (см. картинку 1 ниже).2. Возможность автоматически генерировать заголовочные комментарии для существующих файлов, проектов и решений с помощью EditorConfig. Вы можете добавить правило
file_header_template
в файл EditorConfig и задать ему нужный заголовок. В первой строке любого файла вызовите Quick Actions and Refactorings > Add file banner. Также здесь вы можете применить заголовок к файлу, всем файлам проекта или решения, в блоке Fix all occurences in: (см. картинки 2 и 3 ниже).3. Теперь вы можете упростить условные выражения, удалив ненужный код, используя новую возможность Simplify conditional expression (см. картинку 4 ниже).
4. Кроме того, появилась новая опция Convert verbatim string, которая позволяет преобразовывать обычные строковые литералы в дословные и обратно (см. картинку 5 ниже).
Источник: https://devblogs.microsoft.com/visualstudio/visual-studio-2019-version-16-6-preview-2/
День четыреста двадцать девятый. #DesignPatterns
Паттерны проектирования
18. Паттерн «Заместитель» (Proxy)
Заместитель позволяет подставлять вместо реальных объектов специальные объекты-заменители, которые перехватывают вызовы к оригинальному объекту, позволяя сделать что-то до или после передачи вызова оригиналу.
Назначение: является суррогатом другого объекта и контролирует доступ к нему.
Причины использования:
Классы-заместители активно применяются там, где нужно спрятать исходный объект и добавить к его методам некоторое поведение: позволить отложить создание дорогостоящего объекта, контролировать количество вызовов метода или спрятать удаленную природу объекта.
Классическая диаграмма приведена на рисунке ниже:
-
-
-
-
Структуры паттернов «Заместитель» и «Декоратор» очень похожи. Каждый из них содержит ссылку на базовый компонент и делегирует ему выполнение всей работы. Но у этих паттернов разное назначение. Декоратор добавляет поведение всем методам интерфейса, позволяя нанизывать расширения одно на другое. Класс-заместитель может выполнять определенные действия, например создавать настоящий компонент по мере необходимости, но он не должен ничего подмешивать в результаты исполнения операции. Кроме того, Заместитель сам управляет жизнью настоящий компонента, а обёртывание Декораторов контролируется клиентом.
В классическом труде «банды четырех» описаны три основных сценария использования паттерна:
1. Удалённый заместитель отвечает за кодирование запроса и его аргументов для работы с компонентом в другом адресном пространстве. Основная идея в том, что клиент может работать с классом-заместителем так, как будто он работает с объектом в собственном адресном пространстве.
2. Виртуальный заместитель может кэшировать дополнительную информацию о реальном компоненте, чтобы отложить его создание. Класс
3. Защищающий заместитель проверяет, имеет ли вызывающий объект необходимые для выполнения запроса права.
Источник: Тепляков С. "Паттерны проектирования на платформе .NET." — СПб.: Питер, 2015. Глава 16.
Паттерны проектирования
18. Паттерн «Заместитель» (Proxy)
Заместитель позволяет подставлять вместо реальных объектов специальные объекты-заменители, которые перехватывают вызовы к оригинальному объекту, позволяя сделать что-то до или после передачи вызова оригиналу.
Назначение: является суррогатом другого объекта и контролирует доступ к нему.
Причины использования:
Классы-заместители активно применяются там, где нужно спрятать исходный объект и добавить к его методам некоторое поведение: позволить отложить создание дорогостоящего объекта, контролировать количество вызовов метода или спрятать удаленную природу объекта.
Классическая диаграмма приведена на рисунке ниже:
-
Client
— работает с абстрактным компонентом, не зная, является он настоящим или нет;-
Subject
— определяет интерфейс компонента;-
Proxy
— объект-заместитель, который реализует интерфейс компонента, но делегирует всю работу настоящему объекту;-
RealSubject
— реальный компонент, доступ к которому осуществляется через заместителя.Структуры паттернов «Заместитель» и «Декоратор» очень похожи. Каждый из них содержит ссылку на базовый компонент и делегирует ему выполнение всей работы. Но у этих паттернов разное назначение. Декоратор добавляет поведение всем методам интерфейса, позволяя нанизывать расширения одно на другое. Класс-заместитель может выполнять определенные действия, например создавать настоящий компонент по мере необходимости, но он не должен ничего подмешивать в результаты исполнения операции. Кроме того, Заместитель сам управляет жизнью настоящий компонента, а обёртывание Декораторов контролируется клиентом.
В классическом труде «банды четырех» описаны три основных сценария использования паттерна:
1. Удалённый заместитель отвечает за кодирование запроса и его аргументов для работы с компонентом в другом адресном пространстве. Основная идея в том, что клиент может работать с классом-заместителем так, как будто он работает с объектом в собственном адресном пространстве.
2. Виртуальный заместитель может кэшировать дополнительную информацию о реальном компоненте, чтобы отложить его создание. Класс
Lazy<T>
можно считать универсальным строительным блоком, с помощью которого легко создавать виртуальные классы-заместители.3. Защищающий заместитель проверяет, имеет ли вызывающий объект необходимые для выполнения запроса права.
Источник: Тепляков С. "Паттерны проектирования на платформе .NET." — СПб.: Питер, 2015. Глава 16.
День четыреста тридцатый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
33. Числа с Плавающей Точкой не Являются Действительными
Числа с плавающей точкой (
Чтобы проиллюстрировать это, присвойте
Знание о таком интервале между числами с плавающей точкой поможет вам избежать классических ошибок при работе с ними. Например, если вы выполняете итеративные вычисления, такие как поиск корня уравнения, нет смысла ожидать большей точности, чем это расстояние. Убедитесь, что заданный вами шаг не меньше, чем интервал между числами, иначе вы попадёте в бесконечный цикл.
Поскольку числа с плавающей точкой являются приближением к действительным числам, неизбежно будет присутствовать неточность. Эта неточность, называемая ошибкой округления, может приводить к удивительным результатам.
Например, когда вы вычитаете почти равные между собой числа, старшие значимые цифры взаимно исключаются, а младшие значимые цифры (где присутствует ошибка округления) переходят на более значимые позиции, что «загрязняет» любые дальнейшие связанные вычисления. Этот эффект получил название «размазывание» («smearing»). Нужно следить за применяемыми алгоритмами, чтобы не допустить этого.
Размазывание может происходить и в менее очевидных случаях. Предположим, вы вычисляете
Это хорошо работает для положительных
Разумеется, нельзя использовать числа с плавающей точкой для финансовых приложений: для этого в таких языках, как Python и C#, используется тип
Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Chuck Allison
97 Вещей, Которые Должен Знать Каждый Программист
33. Числа с Плавающей Точкой не Являются Действительными
Числа с плавающей точкой (
float
) не являются действительными (real
) числами в математическом смысле, даже если они называются так в некоторых языках программирования, таких как Паскаль и Фортран. Действительные числа имеют бесконечную точность и поэтому непрерывны. Числа с плавающей точкой имеют ограниченную точность, поэтому они конечны и ведут себя как «непослушные» целые, т.к. даже не покрывают весь диапазон целых чисел.Чтобы проиллюстрировать это, присвойте
2147483647
(самое большое 32-разрядное целое число со знаком) 32-разрядной переменной с плавающей точкой (скажем, x
) и распечатайте её, затем значение x-64
, а затем x-65
:float x = 2147483647;Получилось
Console.WriteLine($"x = {x:F0}");
Console.WriteLine($"x-64 = {(x-64):F0}");
Console.WriteLine($"x-65 = {(x-65):F0}");
x = 2147483648Почему? Потому что интервал между соседними числами с плавающей точкой в этом диапазоне равен 128, и результат округляется до ближайшего числа.
x-64 = 2147483648
x-65 = 2147483520
Знание о таком интервале между числами с плавающей точкой поможет вам избежать классических ошибок при работе с ними. Например, если вы выполняете итеративные вычисления, такие как поиск корня уравнения, нет смысла ожидать большей точности, чем это расстояние. Убедитесь, что заданный вами шаг не меньше, чем интервал между числами, иначе вы попадёте в бесконечный цикл.
Поскольку числа с плавающей точкой являются приближением к действительным числам, неизбежно будет присутствовать неточность. Эта неточность, называемая ошибкой округления, может приводить к удивительным результатам.
Например, когда вы вычитаете почти равные между собой числа, старшие значимые цифры взаимно исключаются, а младшие значимые цифры (где присутствует ошибка округления) переходят на более значимые позиции, что «загрязняет» любые дальнейшие связанные вычисления. Этот эффект получил название «размазывание» («smearing»). Нужно следить за применяемыми алгоритмами, чтобы не допустить этого.
Размазывание может происходить и в менее очевидных случаях. Предположим, вы вычисляете
e^x
по формуле1 + x + x^2/2 + x^3/3! + …
Это хорошо работает для положительных
x
. Но, когда х
- большое отрицательное число, чётные степени х становятся большими положительными числами, а вычитание нечётных степеней даже не влияет на результат. Проблема здесь в том, что ошибка округления для больших положительных чисел оказывается значительно больше истинного ответа. В результате ответ стремится к положительной бесконечности! Решение здесь простое: для отрицательных x вычисляйте e^x
как 1/e^|x|
.Разумеется, нельзя использовать числа с плавающей точкой для финансовых приложений: для этого в таких языках, как Python и C#, используется тип
decimal
. Числа с плавающей точкой предназначены для эффективных научных расчётов. Однако эффективность бесполезна без нужной точности, поэтому помните об источнике ошибок округления при написании кода!Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Chuck Allison
День четыреста тридцать первый. #MoreEffectiveCSharp
7. Ограничивайте Область Действия Типа, Используя Анонимные Типы
Для создания пользовательских типов, представляющих объекты и структуры данных программы, вы можете выбрать классы, структуры, кортежи или анонимные типы. Классы и структуры настолько богаты в смысле выражения ваших замыслов, что заставляют многих разработчиков выбирать их, не рассматривая другие возможности. Вы можете написать более читаемый код, используя более простые конструкции: анонимные типы или кортежи.
Анонимные типы — это генерируемые компилятором неизменяемые ссылочные типы, которые можно объявить так:
- новый закрытый (sealed) класс,
- этот новый тип является неизменяемым,
- тип имеет два открытых свойства только для чтения X и Y.
Преимущества
1. Код короче и меньше подвержен ошибкам.
2. Область действия анонимного типа ограничена методом, в котором он определён. Таким образом тип не загрязняет пространство имён, а ясно показывает другим разработчикам, что он используется для промежуточных вычислений только в пределах этого единственного метода.
3. Для обычных классов вы не можете задавать значения свойств только для чтения через инициализатор объекта, так как это позволяют делать анонимные типы.
4. Компилятор создаёт оптимизированный код. Всякий раз, когда вы создаёте такой же анонимный тип, компилятор не генерирует новый тип, а использует уже существующий*.
*Примечание: 1) очевидно, что это происходит, только если несколько копий анонимного типа объявлены в одной сборке, 2) имена, типы и порядок свойств анонимных типов должны совпадать.
5. Анонимные типы могут использоваться как составные ключи. Предположим, что вам нужно сгруппировать клиентов по продавцу и почтовому индексу. Вы можете выполнить запрос:
Очевидным недостатком использования анонимных типов является то, что вы не знаете названия типа, а значит не можете использовать его в качестве параметра метода или возвращаемого значения. Тем не менее, есть способы работы с отдельными объектами или последовательностями анонимных типов, используя обобщённые методы и лямбда выражения. Например, имея обобщённый метод преобразования:
Совместимость типов C# обычно основана на имени типа и называется номинативной типизацией. Кортежи используют структурную типизацию, а не номинативную, чтобы определить, относятся ли разные объекты к одному и тому же типу. Кортежи полагаются на свою «форму», а не на имя для определения конкретного типа. Таким образом любой кортеж, который содержит 2 целых числа, будет того же типа, что кортеж point выше. Заметки по использованию кортежей.
Источник: Bill Wagner “More Effective C#”. – 2nd ed. Глава 7.
7. Ограничивайте Область Действия Типа, Используя Анонимные Типы
Для создания пользовательских типов, представляющих объекты и структуры данных программы, вы можете выбрать классы, структуры, кортежи или анонимные типы. Классы и структуры настолько богаты в смысле выражения ваших замыслов, что заставляют многих разработчиков выбирать их, не рассматривая другие возможности. Вы можете написать более читаемый код, используя более простые конструкции: анонимные типы или кортежи.
Анонимные типы — это генерируемые компилятором неизменяемые ссылочные типы, которые можно объявить так:
var point = new {X = 5, Y = 67};Вы указали компилятору, что вам нужен
- новый закрытый (sealed) класс,
- этот новый тип является неизменяемым,
- тип имеет два открытых свойства только для чтения X и Y.
Преимущества
1. Код короче и меньше подвержен ошибкам.
2. Область действия анонимного типа ограничена методом, в котором он определён. Таким образом тип не загрязняет пространство имён, а ясно показывает другим разработчикам, что он используется для промежуточных вычислений только в пределах этого единственного метода.
3. Для обычных классов вы не можете задавать значения свойств только для чтения через инициализатор объекта, так как это позволяют делать анонимные типы.
4. Компилятор создаёт оптимизированный код. Всякий раз, когда вы создаёте такой же анонимный тип, компилятор не генерирует новый тип, а использует уже существующий*.
*Примечание: 1) очевидно, что это происходит, только если несколько копий анонимного типа объявлены в одной сборке, 2) имена, типы и порядок свойств анонимных типов должны совпадать.
5. Анонимные типы могут использоваться как составные ключи. Предположим, что вам нужно сгруппировать клиентов по продавцу и почтовому индексу. Вы можете выполнить запрос:
var query = from c in customersОн создаст словарь, в котором ключами будут пары
group c by new { c.SalesRep, c.ZipCode };
SalesRep
и ZipCode
, а значениями - списки клиентов.Очевидным недостатком использования анонимных типов является то, что вы не знаете названия типа, а значит не можете использовать его в качестве параметра метода или возвращаемого значения. Тем не менее, есть способы работы с отдельными объектами или последовательностями анонимных типов, используя обобщённые методы и лямбда выражения. Например, имея обобщённый метод преобразования:
static T Transform<T> (T e, Func<T, T> func) {можно удвоить значения
return func(e);
}
X
и Y
для точки, передав анонимный тип и функцию преобразования в метод Transform
:var p1 = new { X = 5, Y = 67 };Кортежи являются изменяемыми значимыми типами с открытыми полями.
var p2 = Transform(p1, (p) => new { X=p.X*2, Y=p.Y*2 });
var point = (X: 5, Y: 67);Создание экземпляра кортежа не генерирует новый тип, как создание нового анонимного типа. Вместо этого создаётся одна из структур
ValueTuple
(их несколько в зависимости от количества элементов кортежа). ValueTuple
содержит методы проверки на равенство, сравнение и метод ToString()
, который печатает значение каждого поля кортежа.Совместимость типов C# обычно основана на имени типа и называется номинативной типизацией. Кортежи используют структурную типизацию, а не номинативную, чтобы определить, относятся ли разные объекты к одному и тому же типу. Кортежи полагаются на свою «форму», а не на имя для определения конкретного типа. Таким образом любой кортеж, который содержит 2 целых числа, будет того же типа, что кортеж point выше. Заметки по использованию кортежей.
Источник: Bill Wagner “More Effective C#”. – 2nd ed. Глава 7.
День четыреста тридцать второй. #ЗаметкиНаПолях
Парсинг Строк в Числа, Используя Перечисление NumberStyles
Рассмотрим следующий код:
Парсинг Строк в Числа, Используя Перечисление NumberStyles
Рассмотрим следующий код:
Console.WriteLine("Пожалуйста, введите число:");Мы просим пользователя ввести число, а затем мы просто читаем ввод с консоли и используем метод
var input = Console.ReadLine();
var number = int.Parse(input);
WriteLine("Ваше число: "+ number);
int.Parse
для преобразования этой строки в int
. Если мы запустим вышеуказанную программу, введём число и нажмем Enter
, мы получим следующий вывод:Пожалуйста, введите число:Но что, если мы введём число с использованием разделителя тысяч:
1000
Ваше число: 1000
1,000
. В этом случае вышеприведенная программа выдаст исключение System.FormatException
. Однако мы можем контролировать, как происходит синтаксический анализ, используя перегрузку метода Parse
, которая позволяет нам указать одно или несколько значений перечисления NumberStyles
, например:var number = int.Parse(input, NumberStyles.AllowThousands);
NumberStyles
имеет целый ряд различных опций для тонкой настройки синтаксического анализа, например, разрешение символа валюты, круглых скобок для представления отрицательных значений, разделителя тысяч и т. д. Мы можем комбинировать значения NumberStyles
, используя оператор побитового или, либо одно из предопределённых значений Any
, None
, Number
, Currency
и т.п.:var number = int.Parse(input, NumberStyles.AllowThousands | NumberStyles.AllowLeadingWhite | NumberStyles.AllowTrailingWhite);Теперь мы можем использовать пробелы до и после числа и разделитель тысяч:
Пожалуйста, введите число:Источник: https://codewithshadman.com/csharp-number-and-datetime-tips/
1,000
Ваше число: 1000
День четыреста тридцать третий. #DesignPatterns
Принципы SOLID
«Сильные знания ООП/ООД, ТВЁРДЫЕ»
(с) Вакансии по .Net
SOLID — мнемонический акроним, введённый Майклом Фэзерсом для пяти основных принципов ООП и проектирования. При создании ПО SOLID способствует созданию такой системы, которую будет легко поддерживать и расширять в течение долгого времени. Принципы SOLID также могут применяться во время работы над существующим программным обеспечением для его улучшения - например для удаления «дурно пахнущего кода».
S. Принцип единственной обязанности (Single Responsibility Principle): у класса/модуля должна быть лишь одна причина для изменения. Данный принцип говорит о борьбе с изменениями, но на самом деле суть его сводится к борьбе со сложностью. Любой сложный класс должен быть разбит на несколько простых составляющих, отвечающих за определённый аспект поведения. Это упрощает как понимание, так и развитие класса в будущем. Простой класс с небольшим числом зависимостей легко изменить независимо от того, сколько причин для изменения существует. Разработчик очень редко знает, как требования изменятся в будущем, что делает простое решение лучшим способом обеспечения гибкости.
O. Принцип «открыт/закрыт» (Open-Closed Principle): программные сущности (классы, модули, функции и т. п.) должны быть открытыми для расширения, но закрытыми для модификации. Любой готовый модуль должен быть стабильным (закрытым) с точки зрения своего интерфейса, но открытым с точки зрения реализации. Закрытость модулей означает стабильность интерфейса и возможность использования модулей его клиентами. Открытость модулей означает возможность его изменения путем изменения реализации или же путем переопределения поведения за счет создания наследников. Сокрытие информации и полиморфизм позволяют ограничить количество изменений, которые понадобится внести в систему при очередном изменении требований, что сделает этот процесс более простым и управляемым.
L. Принцип замещения Лисков (Liskov Substitution Principle): должна существовать возможность вместо базового типа подставить любой его подтип. Поскольку наследование является одним из ключевых механизмов ООП, очень важно использовать его корректным образом. Данный принцип даёт чёткие рекомендации о том, в каких пределах может изменяться поведение методов, переопределённых в производных классах, чтобы между классами сохранялось отношение «ЯВЛЯЕТСЯ».
I. Принцип разделения интерфейсов (Interface Segregation Principle): клиенты не должны вынужденно зависеть от методов, которыми не пользуются. Интерфейс класса определяется некоторым контрактом, которому он должен следовать ради своих клиентов. Иногда возникают ситуации, когда у разных клиентов появляются различные сценарии использования класса, в результате чего его интерфейс становится несогласованным и неудобным в использовании. Данный принцип говорит о том, что клиенты хотят иметь цельный и согласованный интерфейс сервисов независимо от того, пользуется ли этими сервисами еще кто-то, кроме них, или нет.
D. Принцип инверсии зависимостей (Dependency Inversion Principle): модули верхнего уровня не должны зависеть от модулей нижнего уровня. И те и другие должны зависеть от абстракций. Слишком большое число зависимостей класса говорит о проблемах в его дизайне. Возможно, класс делает слишком многое или же он неудачно спроектирован, что приводит к необходимости вызова по одному методу у большого числа зависимостей. Любая объектная система представляет собой граф взаимодействующих объектов. При этом некоторые зависимости являются деталями реализации и контролируются классами самостоятельно, а некоторые должны передаваться извне при конструировании объектов. Данный принцип говорит о необходимости выделения и передачи ключевых зависимостей через аргументы конструктора, что позволяет перенести проблемы создания и выбора конкретных зависимостей на вызывающий код.
Источники:
- Тепляков С. "Паттерны проектирования на платформе .NET." — СПб.: Питер, 2015. Глава 17.
- https://ru.wikipedia.org/wiki/SOLID
Принципы SOLID
«Сильные знания ООП/ООД, ТВЁРДЫЕ»
(с) Вакансии по .Net
SOLID — мнемонический акроним, введённый Майклом Фэзерсом для пяти основных принципов ООП и проектирования. При создании ПО SOLID способствует созданию такой системы, которую будет легко поддерживать и расширять в течение долгого времени. Принципы SOLID также могут применяться во время работы над существующим программным обеспечением для его улучшения - например для удаления «дурно пахнущего кода».
S. Принцип единственной обязанности (Single Responsibility Principle): у класса/модуля должна быть лишь одна причина для изменения. Данный принцип говорит о борьбе с изменениями, но на самом деле суть его сводится к борьбе со сложностью. Любой сложный класс должен быть разбит на несколько простых составляющих, отвечающих за определённый аспект поведения. Это упрощает как понимание, так и развитие класса в будущем. Простой класс с небольшим числом зависимостей легко изменить независимо от того, сколько причин для изменения существует. Разработчик очень редко знает, как требования изменятся в будущем, что делает простое решение лучшим способом обеспечения гибкости.
O. Принцип «открыт/закрыт» (Open-Closed Principle): программные сущности (классы, модули, функции и т. п.) должны быть открытыми для расширения, но закрытыми для модификации. Любой готовый модуль должен быть стабильным (закрытым) с точки зрения своего интерфейса, но открытым с точки зрения реализации. Закрытость модулей означает стабильность интерфейса и возможность использования модулей его клиентами. Открытость модулей означает возможность его изменения путем изменения реализации или же путем переопределения поведения за счет создания наследников. Сокрытие информации и полиморфизм позволяют ограничить количество изменений, которые понадобится внести в систему при очередном изменении требований, что сделает этот процесс более простым и управляемым.
L. Принцип замещения Лисков (Liskov Substitution Principle): должна существовать возможность вместо базового типа подставить любой его подтип. Поскольку наследование является одним из ключевых механизмов ООП, очень важно использовать его корректным образом. Данный принцип даёт чёткие рекомендации о том, в каких пределах может изменяться поведение методов, переопределённых в производных классах, чтобы между классами сохранялось отношение «ЯВЛЯЕТСЯ».
I. Принцип разделения интерфейсов (Interface Segregation Principle): клиенты не должны вынужденно зависеть от методов, которыми не пользуются. Интерфейс класса определяется некоторым контрактом, которому он должен следовать ради своих клиентов. Иногда возникают ситуации, когда у разных клиентов появляются различные сценарии использования класса, в результате чего его интерфейс становится несогласованным и неудобным в использовании. Данный принцип говорит о том, что клиенты хотят иметь цельный и согласованный интерфейс сервисов независимо от того, пользуется ли этими сервисами еще кто-то, кроме них, или нет.
D. Принцип инверсии зависимостей (Dependency Inversion Principle): модули верхнего уровня не должны зависеть от модулей нижнего уровня. И те и другие должны зависеть от абстракций. Слишком большое число зависимостей класса говорит о проблемах в его дизайне. Возможно, класс делает слишком многое или же он неудачно спроектирован, что приводит к необходимости вызова по одному методу у большого числа зависимостей. Любая объектная система представляет собой граф взаимодействующих объектов. При этом некоторые зависимости являются деталями реализации и контролируются классами самостоятельно, а некоторые должны передаваться извне при конструировании объектов. Данный принцип говорит о необходимости выделения и передачи ключевых зависимостей через аргументы конструктора, что позволяет перенести проблемы создания и выбора конкретных зависимостей на вызывающий код.
Источники:
- Тепляков С. "Паттерны проектирования на платформе .NET." — СПб.: Питер, 2015. Глава 17.
- https://ru.wikipedia.org/wiki/SOLID
День четыреста тридцать четвёртый. #Оффтоп
Git
Как работается/отдыхается на самоизоляции? Свободного времени должно быть много, поэтому ловите аж целых два часовых видео про Git.
Начнём с основ. Видео «Git Fundamentals» с канала Microsoft Visual Studio - одно из самых подробных объяснений принципов работы Git и демонстрации работы как отдельного инструмента через консоль, так и с помощью Visual Studio. Кстати, в VS 16.6 функционал Git будет модернизирован.
Ну а те, кто уже знаком с инструментом, могут посмотреть видео от NDC Conferences «How Effective Teams Use Git» про эффективное использование Git.
Git
Как работается/отдыхается на самоизоляции? Свободного времени должно быть много, поэтому ловите аж целых два часовых видео про Git.
Начнём с основ. Видео «Git Fundamentals» с канала Microsoft Visual Studio - одно из самых подробных объяснений принципов работы Git и демонстрации работы как отдельного инструмента через консоль, так и с помощью Visual Studio. Кстати, в VS 16.6 функционал Git будет модернизирован.
Ну а те, кто уже знаком с инструментом, могут посмотреть видео от NDC Conferences «How Effective Teams Use Git» про эффективное использование Git.
YouTube
Git Fundamentals
Git is a free, open source distributed version control system. It has become wildly popular as a way to not only manage source code, but also as a way of sharing code with others.
In this episode, Robert demonstrates the basics of using Git. In the first…
In this episode, Robert demonstrates the basics of using Git. In the first…
День четыреста тридцать пятый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
34. Исполняйте Мечты в Открытом Коде
Очень вероятно, что на своей работе вы не разрабатываете ПО, о котором мечтаете. Возможно, вы работаете над ПО для большой страховой компании, но мечтаете работать в Google, Apple, Microsoft или в собственном стартапе, разрабатывающем новый Твиттер. Ваши мечты никогда не исполнятся, если вы разрабатываете ПО для систем, которые вам не нужны.
К счастью, есть решение вашей проблемы: открытый исходный код. Существуют тысячи проектов с открытым кодом, многие из которых довольно активны, и предлагают вам любой опыт разработки, который вы можете пожелать. Если вам нравится разработка операционных систем, рассмотрите один из десятков проектов операционных систем. Если вы хотите работать над музыкальным ПО, анимацией, криптографией, робототехникой, компьютерными играми, крупными онлайн-играми, мобильными системами и т. д., вы почти наверняка найдёте хотя бы один проект с открытым исходным кодом, посвящённый этому.
Конечно, всё имеет свою цену. Вы должны быть готовы пожертвовать своим свободным временем, потому что вы, вероятно, не сможете работать над видеоигрой с открытым кодом на своей повседневной работе - вы по-прежнему несете ответственность перед своим работодателем. Кроме того, очень немногие зарабатывают деньги, участвуя в таких проектах (некоторые да, но большинство нет). Вы должны быть готовы отдать часть своего свободного времени (меньше времени на видеоигры и просмотр телевизора пойдёт вам только на пользу). Чем усерднее вы работаете над проектом с открытым кодом, тем быстрее вы реализуете свои истинные амбиции программиста. Тут важно учитывать ваш рабочий контракт: некоторые работодатели могут ограничивать то, что вы можете делать даже в собственное время. Кроме того, вы должны быть осторожны с нарушением законов об интеллектуальной собственности, авторском праве, патентами, товарными знаками и коммерческой тайной.
Открытый код предоставляет огромные возможности для мотивированного программиста. Во-первых, вы узнаете, как кто-то другой может реализовать интересующее вас решение - вы можете многому научиться, читая исходный код других людей. Во-вторых, вы можете внести свой собственный код и идеи в проект. Не все ваши блестящие идеи будут приняты, но некоторые пройдут, и вы обязательно узнаете что-то новое, просто работая над проектом и добавляя код. В-третьих, вы встретите замечательных людей с такой же страстью к тому же типу ПО, что и у вас. В-четвёртых, если вы компетентный участник, вы сможете принести реальную пользу технологии, которая вас действительно интересует.
Начать работать с открытым кодом довольно просто. Существует множество документации по необходимым инструментам (управление исходным кодом, редакторы, языки программирования, системы сборки и т. д.). Для начала найдите проект, над которым вы хотите работать, и узнайте об инструментах, которые он использует. Документация по самому проекту в большинстве случаев будет скудной, но это, возможно, и хорошо, потому что лучший способ научиться — это исследовать код самостоятельно. Если вы захотите принять участие, вы можете предложить помощь с документацией или начать с написания кода тестов. Это может показаться неинтересным, но дело в том, что вы научитесь гораздо быстрее при написании тестового кода для ПО других людей. Пишите тестовый код, действительно хороший тестовый код, находите ошибки, предлагайте исправления, заводите друзей, работайте над понравившимся ПО и исполняйте свои мечты в разработке.
Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Richard Monson-Haefel
97 Вещей, Которые Должен Знать Каждый Программист
34. Исполняйте Мечты в Открытом Коде
Очень вероятно, что на своей работе вы не разрабатываете ПО, о котором мечтаете. Возможно, вы работаете над ПО для большой страховой компании, но мечтаете работать в Google, Apple, Microsoft или в собственном стартапе, разрабатывающем новый Твиттер. Ваши мечты никогда не исполнятся, если вы разрабатываете ПО для систем, которые вам не нужны.
К счастью, есть решение вашей проблемы: открытый исходный код. Существуют тысячи проектов с открытым кодом, многие из которых довольно активны, и предлагают вам любой опыт разработки, который вы можете пожелать. Если вам нравится разработка операционных систем, рассмотрите один из десятков проектов операционных систем. Если вы хотите работать над музыкальным ПО, анимацией, криптографией, робототехникой, компьютерными играми, крупными онлайн-играми, мобильными системами и т. д., вы почти наверняка найдёте хотя бы один проект с открытым исходным кодом, посвящённый этому.
Конечно, всё имеет свою цену. Вы должны быть готовы пожертвовать своим свободным временем, потому что вы, вероятно, не сможете работать над видеоигрой с открытым кодом на своей повседневной работе - вы по-прежнему несете ответственность перед своим работодателем. Кроме того, очень немногие зарабатывают деньги, участвуя в таких проектах (некоторые да, но большинство нет). Вы должны быть готовы отдать часть своего свободного времени (меньше времени на видеоигры и просмотр телевизора пойдёт вам только на пользу). Чем усерднее вы работаете над проектом с открытым кодом, тем быстрее вы реализуете свои истинные амбиции программиста. Тут важно учитывать ваш рабочий контракт: некоторые работодатели могут ограничивать то, что вы можете делать даже в собственное время. Кроме того, вы должны быть осторожны с нарушением законов об интеллектуальной собственности, авторском праве, патентами, товарными знаками и коммерческой тайной.
Открытый код предоставляет огромные возможности для мотивированного программиста. Во-первых, вы узнаете, как кто-то другой может реализовать интересующее вас решение - вы можете многому научиться, читая исходный код других людей. Во-вторых, вы можете внести свой собственный код и идеи в проект. Не все ваши блестящие идеи будут приняты, но некоторые пройдут, и вы обязательно узнаете что-то новое, просто работая над проектом и добавляя код. В-третьих, вы встретите замечательных людей с такой же страстью к тому же типу ПО, что и у вас. В-четвёртых, если вы компетентный участник, вы сможете принести реальную пользу технологии, которая вас действительно интересует.
Начать работать с открытым кодом довольно просто. Существует множество документации по необходимым инструментам (управление исходным кодом, редакторы, языки программирования, системы сборки и т. д.). Для начала найдите проект, над которым вы хотите работать, и узнайте об инструментах, которые он использует. Документация по самому проекту в большинстве случаев будет скудной, но это, возможно, и хорошо, потому что лучший способ научиться — это исследовать код самостоятельно. Если вы захотите принять участие, вы можете предложить помощь с документацией или начать с написания кода тестов. Это может показаться неинтересным, но дело в том, что вы научитесь гораздо быстрее при написании тестового кода для ПО других людей. Пишите тестовый код, действительно хороший тестовый код, находите ошибки, предлагайте исправления, заводите друзей, работайте над понравившимся ПО и исполняйте свои мечты в разработке.
Источник: https://www.oreilly.com/library/view/97-things-every/9780596809515/
Автор оригинала – Richard Monson-Haefel
День четыреста тридцать шестой. #ЗаметкиНаПолях
Предотвращаем Неоднозначный или Неправильный Парсинг Даты
«Что джун, что сеньор при работе с датами всегда будет смотреть в документацию.»
Старая поговорка
Рассмотрим следующий код:
Так же, как и с перечислением NumberStyles для чисел, можно использовать перечисление
Стандартный парсинг даты (вывод может отличаться в зависимости от настроек компьютера):
Предотвращаем Неоднозначный или Неправильный Парсинг Даты
«Что джун, что сеньор при работе с датами всегда будет смотреть в документацию.»
Старая поговорка
Рассмотрим следующий код:
Console.WriteLine("Введите дату рождения:");Приведенная выше программа генерирует следующий результат:
var input = Console.ReadLine();
var dob = DateTime.Parse(input);
Console.WriteLine("Дата рождения: " + dob.ToShortDateString());
Введите дату рождения:Здесь может быть непонятно, какое число является днём, а какое месяцем. Мы можем предотвратить неправильный парсинг даты, указав точный формат, который мы ожидаем, с помощью
3/6/1995
Дата рождения: 03-06-1995
DateTime.ParseExact
:var dob = DateTime.ParseExact(input, "MM/dd/yyyy", null);Помимо строки для парсинга указывается желаемый формат, а также объект провайдера формата. Получится следующее (заметьте, что в дате и месяце обязательны нули в начале, а год должен быть четырёхзначным):
Введите дату рождения:Разбор DateTime с помощью DateTimeStyles
06/03/1995
Дата рождения: 03-06-1995
Так же, как и с перечислением NumberStyles для чисел, можно использовать перечисление
DateStyles
для подсказки парсеру, как трактовать входящий параметр даты.Стандартный парсинг даты (вывод может отличаться в зависимости от настроек компьютера):
var d1 = DateTime.Parse("01/12/2000");Местное время явно:
//01-12-2000 00:00:00
var d2 = DateTime.Parse("01/12/2000", null, DateTimeStyles.AssumeLocal);Универсальное время (выводится местное время: для Москвы +3):
//01-12-2000 00:00:00
var d3 = DateTime.Parse("01/12/2000", null, DateTimeStyles.AssumeUniversal);Стандартный парсинг времени:
DateTime d4 = DateTime.Parse("13:30:00");Время без даты:
//10-04-2020 13:30:00 (текущая дата)
DateTime d5 = DateTime.Parse("13:30:00", null, DateTimeStyles.NoCurrentDateDefault);Источник: https://codewithshadman.com/csharp-number-and-datetime-tips/
//01-01-0001 13:30:00
День четыреста тридцать седьмой. #ЗаметкиНаПолях
ASP.NET MVC. Маршрутизация. Начало
Традиционно во многих веб-средах URL-адрес представлял собой физический файл на диске. Запрос к URL принимался веб-сервером, который выполнял некоторый код в этом файле для получения ответа. В MVC в большинстве случаев используется другой подход - отображение URL-адреса на вызов метода в классе.
Система маршрутизации работает с использованием множества маршрутов. Вместе маршруты образуют схему URL приложения, представляющую собой набор URL, которые приложение будет распознавать и реагировать на них. Каждый маршрут содержит шаблон URL, с которым сравниваются входящие URL. Если входящий URL соответствует шаблону, тогда он применяется системой маршрутизации для обработки этого URL. URL могут быть разбиты на сегменты - части URL кроме имени хоста и строки запроса, которые отделяются друг от друга символом
Подходы маршрутизации
Централизованный стиль определения маршрутов в одном месте называется традиционной маршрутизацией или маршрутизацией на основе соглашений. Начиная с MVC 5, есть другой вариант, использующий атрибуты контроллеров и методов действий, который называется маршрутизацией с помощью атрибутов.
При использовании маршрутизации с помощью атрибутов маршрут определяется отдельно для каждого контроллера или даже для каждого метода действия, с помощью атрибута Route.
К маршрутам, заданным в атрибутах, можно применить все те же расширения и ограничения, как и к традиционным. Они будут рассмотрены далее.
Традиционные маршруты определяются:
- в .Net Framework - в методе
- Иметь централизованную настройку всех маршрутов.
- Использовать пользовательские объекты ограничений.
Маршруты с использованием атрибутов имеет смысл использовать для новых приложений, если вы хотите хранить маршруты вместе с кодом методов действий.
Оба типа можно использовать совместно. На практике маршруты, заданные атрибутами, обычно более специфичны, поэтому в .Net Framework рекомендовано расположить вызов
Продолжение следует…
Источники:
- Jon Galloway “Professional ASP.NET MVC 5”. – John Wiley & Sons Inc., 2014. Глава 9.
- Адам Фримен “Pro ASP.NET Core MVC 2”. – Диалектика, 2019. Глава 15.
ASP.NET MVC. Маршрутизация. Начало
Традиционно во многих веб-средах URL-адрес представлял собой физический файл на диске. Запрос к URL принимался веб-сервером, который выполнял некоторый код в этом файле для получения ответа. В MVC в большинстве случаев используется другой подход - отображение URL-адреса на вызов метода в классе.
Система маршрутизации работает с использованием множества маршрутов. Вместе маршруты образуют схему URL приложения, представляющую собой набор URL, которые приложение будет распознавать и реагировать на них. Каждый маршрут содержит шаблон URL, с которым сравниваются входящие URL. Если входящий URL соответствует шаблону, тогда он применяется системой маршрутизации для обработки этого URL. URL могут быть разбиты на сегменты - части URL кроме имени хоста и строки запроса, которые отделяются друг от друга символом
/
. Например, https://mysite.com/Admin/Index
содержит два сегмента Admin
и Index
.Подходы маршрутизации
Централизованный стиль определения маршрутов в одном месте называется традиционной маршрутизацией или маршрутизацией на основе соглашений. Начиная с MVC 5, есть другой вариант, использующий атрибуты контроллеров и методов действий, который называется маршрутизацией с помощью атрибутов.
При использовании маршрутизации с помощью атрибутов маршрут определяется отдельно для каждого контроллера или даже для каждого метода действия, с помощью атрибута Route.
[Route("home/[action]")]Кроме того, с помощью атрибутов можно переименовывать действия в контроллере:
public class HomeController : Controller {…}
[Route("[controller]/MyAction")]Тогда метод действия Index можно будет вызвать только по пути
public ViewResult Index() …
/<имя контроллера>/MyAction
.К маршрутам, заданным в атрибутах, можно применить все те же расширения и ограничения, как и к традиционным. Они будут рассмотрены далее.
Традиционные маршруты определяются:
- в .Net Framework - в методе
RegisterRoutes
файла App_Start/RouteConfig.cs
:public static void RegisterRoutes(RouteCollection routes) {- в .Net Core - в методе
routes.MapRoute("", "{controller}/{action}");
}
Configure
файла Startup.cs
:public void Configure(IApplicationBuilder арр, IHostingEnvironment env) {Принцип определения маршрутов похож. Суть сводится к добавлению маршрута в коллекцию, для чего удобнее всего использовать метод
…
app.UseMvc(routes => { routes.MapRoute("", "{controller}/{action}");
}
MapRoute
:routes.МapRoute(name: "default", template: "{controller}/{action}");Использовать традиционные маршруты или атрибуты зависит от ваших предпочтений. Обычно традиционные маршруты используют для существующих приложений, когда хотят:
- Иметь централизованную настройку всех маршрутов.
- Использовать пользовательские объекты ограничений.
Маршруты с использованием атрибутов имеет смысл использовать для новых приложений, если вы хотите хранить маршруты вместе с кодом методов действий.
Оба типа можно использовать совместно. На практике маршруты, заданные атрибутами, обычно более специфичны, поэтому в .Net Framework рекомендовано расположить вызов
routes.MapMvcAttributeRoutes();
перед определением традиционных маршрутов. В .Net Core этого делать не требуется, маршрут, определённый атрибутом, будет иметь приоритет перед стандартной конфигурацией. Продолжение следует…
Источники:
- Jon Galloway “Professional ASP.NET MVC 5”. – John Wiley & Sons Inc., 2014. Глава 9.
- Адам Фримен “Pro ASP.NET Core MVC 2”. – Диалектика, 2019. Глава 15.
День четыреста тридцать восьмой. #ЗаметкиНаПолях
ASP.NET MVC. Маршрутизация. Продолжение
Принципы поведения шаблонов
- Шаблоны URL консервативны в отношении количества сопоставляемых сегментов. Совпадение будет происходить только для тех URL, которые имеют то же самое количество сегментов, что и шаблон.
- Шаблоны URL либеральны в отношении содержимого сопоставляемых сегментов. Если URL имеет правильное количество сегментов, то шаблон извлечет значение каждого сегмента для переменной сегмента, каким бы оно ни было.
Контролировать поведение системы маршрутизации, можно через шаблоны маршрутов. Сначала рассмотрим, как управлять консервативностью количества сопоставляемых сегментов.
1. Статические значения сегментов
-
2. Определение значений по умолчанию
Любому сегменту можно задать значение по умолчанию, тогда при отсутствии сегмента во входящем URL будет использовано это значение:
3. Специальные переменные сегментов
Можно добавить любое количество сегментов, с именами переменных, которым будут заданы значения из входящего URL:
Шаблоны URL могут иметь несколько переменных в одном сегменте:
Необязательный сегмент может не указываться во входящем маршруте, и тогда он не получит значения. Необязательные сегменты обозначаются знаком
Можно использовать переменную общего захвата (catch-all), которая будет соответствовать неограниченному количеству сегментов. Она обозначается знаком
Источники:
- Jon Galloway “Professional ASP.NET MVC 5”. – John Wiley & Sons Inc., 2014. Глава 9.
- Адам Фримен “Pro ASP.NET Core MVC 2”. – Диалектика, 2019. Глава 15.
ASP.NET MVC. Маршрутизация. Продолжение
Принципы поведения шаблонов
- Шаблоны URL консервативны в отношении количества сопоставляемых сегментов. Совпадение будет происходить только для тех URL, которые имеют то же самое количество сегментов, что и шаблон.
- Шаблоны URL либеральны в отношении содержимого сопоставляемых сегментов. Если URL имеет правильное количество сегментов, то шаблон извлечет значение каждого сегмента для переменной сегмента, каким бы оно ни было.
Контролировать поведение системы маршрутизации, можно через шаблоны маршрутов. Сначала рассмотрим, как управлять консервативностью количества сопоставляемых сегментов.
1. Статические значения сегментов
-
routes.MapRoute(name: "", template: "Public/{controller }/{action }");
URL должен содержать сегмент Public
: https://mysite.com/Public/Home/Index
- routes.MapRoute("", "Х{controller}/{action}");
Первый сегмент URL должен начинаться с X
, но будет соответствовать контроллеру без X
. Например, https://mysite.com/XHome/Index
будет соответствовать контроллеру HomeController
, методу Index
.2. Определение значений по умолчанию
Любому сегменту можно задать значение по умолчанию, тогда при отсутствии сегмента во входящем URL будет использовано это значение:
routes.MapRoute(name: "", template: "{controller}/{action}", defaults: new {action="Index"});Также можно использовать встраиваемые значения внутри шаблона:
routes.MapRoute("", template: "{controller=Home}/{action=Index}");*Если вы определили значение по умолчанию для сегмента, убедитесь, что все сегменты, следующие за ним, также имеют значения по умолчанию. Например, нельзя определить значение по умолчанию для контроллера и не определить его для действия.
3. Специальные переменные сегментов
Можно добавить любое количество сегментов, с именами переменных, которым будут заданы значения из входящего URL:
routes.MapRoute("", "(controller}/{action}/{id=0}");Имена переменных могут быть любыми, кроме зарезервированных слов
controller
, action
и area
. Получить значения этих переменных из метода действия можно либо через словарь RouteData.Values
:var id = RouteData.Values[“id”];Либо используя привязку модели. Если метод действия определяет параметры с именами, которые совпадают с именами переменных шаблона URL, то инфраструктура MVC будет автоматически передавать методу действия значения, извлеченные из URL, в виде аргументов и попытается привести их к типу аргумента:
public ViewResult List(int id) {…}4. Несколько переменных в сегменте
Шаблоны URL могут иметь несколько переменных в одном сегменте:
{title}-{artist}Единственное ограничение – они не должны следовать непосредственно друг за другом, чтобы избежать неоднозначности:
Album{title}and{artist}
{filename}.{ext}
{title}{artist}5. Необязательные сегменты
Необязательный сегмент может не указываться во входящем маршруте, и тогда он не получит значения. Необязательные сегменты обозначаются знаком
?
:routes.MapRoute("", "(controller}/{action}/{id?}");6. Маршруты переменной длины
Можно использовать переменную общего захвата (catch-all), которая будет соответствовать неограниченному количеству сегментов. Она обозначается знаком
*
перед именем:routes.MapRoute("", "{controller}/{action}/{*catchall}");В этом случае переменная
catchall
будет содержать строку со всеми сегментами после второго:https://mysite.com/Home/Index/1/2/3Продолжение следует…
var catchall = RouteData.Values[“catchall”]; // “1/2/3”
Источники:
- Jon Galloway “Professional ASP.NET MVC 5”. – John Wiley & Sons Inc., 2014. Глава 9.
- Адам Фримен “Pro ASP.NET Core MVC 2”. – Диалектика, 2019. Глава 15.