<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/">
  <channel>
    <language>ru</language>
    <title>Asp.NET</title>
    <description/>
    <link>https://tproger.ru/tag/asp-net</link>
    <atom:link href="https://tproger.ru/tag/asp-net/feed" rel="self" type="application/rss+xml"/>
    <lastBuildDate>Tue, 29 Sep 2026 14:51:51 GMT</lastBuildDate>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>12</sy:updateFrequency>
    <image>
      <title>Asp.NET</title>
      <link>https://tproger.ru</link>
      <url>https://tproger.ru/apple-touch-icon.png</url>
    </image>
    <item>
      <title>Microsoft срочно патчит ASP.NET Core: подделка cookie даёт SYSTEM</title>
      <link>https://tproger.ru/news/microsoft-srochno-patchit-asp-net-core-poddelka-cookie-dayot-syste</link>
      <comments>https://tproger.ru/news/microsoft-srochno-patchit-asp-net-core-poddelka-cookie-dayot-syste?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/microsoft-srochno-patchit-asp-net-core-poddelka-cookie-dayot-syste</guid>
      <description><![CDATA[<p>Microsoft выпустила .NET 10.0.7 — критический патч CVE-2026-40372 в ASP.NET Core (CVSS 9,1). Разбираем атаку, какие версии уязвимы и какие ключи ротировать.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/microsoft-srochno-patchit-asp-net-core-poddelka-cookie-dayot-syste">Microsoft срочно патчит ASP.NET Core: подделка cookie даёт SYSTEM</a>»</p>]]></description>
      <category><![CDATA[Уязвимость]]></category>
      <category><![CDATA[Asp.NET]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 23 Apr 2026 10:06:43 GMT</pubDate>
      <content:encoded><![CDATA[<p>Если у вас прод на ASP.NET Core 10 — остановите любую работу и проверьте, какую версию Microsoft.AspNetCore.DataProtection тянет ваше приложение. CVE-2026-40372 с CVSS 9,1 уже закрывают — дочитайте, пока обновляетесь.</p><p>21 апреля 2026 года Microsoft выпустила внеплановое обновление .NET 10.0.7 и опубликовала <a href="https://github.com/dotnet/announcements/issues/395">security advisory CVE-2026-40372</a>. Регрессия в пакете Microsoft.AspNetCore.DataProtection версий 10.0.0–10.0.6 позволяет атакующему без аутентификации подделать auth-cookie и залогиниться под админом приложения — а на Windows-деплоях это открывает путь и к SYSTEM-привилегиям на сервере.</p><p>Уязвимы версии 10.0.0–10.0.6 NuGet-пакета Microsoft.AspNetCore.DataProtection. Фикс — 10.0.7, вышел 21 апреля 2026 как out-of-band релиз.</p><p>Ошибка в HMAC-валидации: managed-энкриптор считает тег не по тем байтам payload и в ряде случаев отбрасывает уже вычисленный хеш.</p><p>Атакующий без аутентификации подделывает защищённые полезные данные: auth-cookie, antiforgery-токены, TempData, OIDC state.</p><p>Обновления пакета недостаточно. Токены, выпущенные за уязвимое окно, остаются валидными, пока вы не ротируете DataProtection key ring.</p><p>Microsoft нашла баг после жалоб пользователей на ошибки дешифровки в .NET 10.0.6 (Patch Tuesday 14 апреля).</p><h2>Что такое ASP.NET Core Data Protection</h2><p><a href="https://learn.microsoft.com/en-us/aspnet/core/security/data-protection/introduction">Data Protection</a> — встроенная в ASP.NET Core подсистема симметричной криптографии. Её задача — аутентифицированно шифровать небольшие полезные нагрузки, которые уходят к клиенту и возвращаются обратно.</p><p>Конкретно — это auth-cookie для логина пользователя, CSRF-токены (antiforgery — защита от межсайтовых запросов), промежуточный TempData (временные данные между двумя запросами одного пользователя), state-параметр в OIDC-флоу (OpenID Connect — протокол авторизации поверх OAuth 2.0), ссылки на сброс пароля и так далее. Всё это — «доверенные конверты», где сервер должен быть уверен, что клиент не подменил содержимое.</p><p>Работает по схеме encrypt-then-MAC: данные шифруются AES-256-CBC, а к шифру добавляется HMAC-SHA256-тег целостности, посчитанный по IV и шифртексту. При расшифровке сервер сначала проверяет HMAC — если тег не сходится, payload отбрасывается как подделанный. Именно в этой проверке и обнаружился баг.</p><h2>В чём баг CVE-2026-40372</h2><p>В версиях 10.0.0–10.0.6 managed-реализация authenticated encryptor в ряде случаев вычисляет HMAC-тег не по тем байтам payload — а затем отбрасывает уже посчитанный хеш. В результате атакующий может сконструировать payload, у которого валидный на вид тег совпадёт с содержимым подделки.</p><p>Microsoft описывает последствия в <a href="https://github.com/dotnet/core/blob/main/release-notes/10.0/10.0.7/10.0.7.md">release notes 10.0.7</a> коротко: поломанная валидация позволяет «подделывать payloads, проходящие проверки подлинности DataProtection, и расшифровывать ранее защищённые данные». На практике это значит, что cookie аутентификации, antiforgery-токены, OIDC state и ссылки сброса пароля перестают быть доверенными контейнерами.</p><p><b>Почему это повышение привилегий:</b> через подделанную auth-cookie атакующий логинится в приложение под привилегированным пользователем — обычно это аккаунт администратора. Дальше приложение само выдаёт ему уже легитимные токены: session-refresh, API-ключи, ссылки сброса пароля. На Windows-деплоях эти токены часто дают доступ к ресурсам, запущенным под NT AUTHORITY\SYSTEM — отсюда и SYSTEM-привилегии в заголовке advisory. CVSS-вектор уязвимости: AV:N/AC:L/PR:N/UI:N/C:H/I:H/A:N — сеть, низкая сложность, без привилегий и взаимодействия.</p><h3>Кого конкретно задевает</h3><ul><li>ASP.NET Core 10-приложения, у которых NuGet-копия Microsoft.AspNetCore.DataProtection версий 10.0.0–10.0.6 действительно загружается в рантайме — это и есть ключевое условие, проверьте lock-файл.</li><li>Linux- и macOS-деплои — на них NuGet-копия пакета подтягивается чаще, чем на Windows: там реже полагаются на shared framework .NET-рантайма. Advisory Microsoft прямо указывает, что Windows-приложения без явной NuGet-зависимости не задеты.</li><li>IdentityServer-решения вроде <a href="https://duendesoftware.com/blog/20260422-update-guidance-for-cve-2026-40372-aspnet-data-protection">Duende</a>, которые используют Data Protection для хранения OIDC-state и refresh-токенов.</li></ul><p>«Shared framework» — это общий рантайм .NET, который ставится в систему отдельно от приложения (Microsoft.AspNetCore.App). «NuGet-копия» — это когда пакет Microsoft.AspNetCore.DataProtection указан в зависимостях проекта напрямую и загружается отдельно, переопределяя версию из shared framework. Разница критична: под уязвимость попадает именно NuGet-копия.</p><h2>Почему одного обновления пакета мало</h2><p>Тонкий момент из advisory, который легко пропустить: если атакующий успел выдать себе легитимные токены во время уязвимого окна (с 14 по 21 апреля для тех, кто накатил 10.0.6 на апрельский Patch Tuesday), эти токены продолжают работать и на 10.0.7. Подписи настоящие, DataProtection key ring тот же.</p><p>Поэтому фикс — это не только обновление NuGet-пакета, но и принудительная ротация DataProtection key ring. Без ротации вы закрываете будущие атаки, но старые уже выпущенные токены продолжат давать доступ.</p><h2>Что делать с CVE-2026-40372 прямо сейчас</h2><ol><li>Обновите версию пакета в csproj или Directory.Packages.props до 10.0.7 — команда в блоке ниже.</li><li>Запустите restore и проверьте уязвимые зависимости. Флаг --include-transitive обязателен: без него вы не увидите пакет, который тянется транзитивно через Identity, Authentication.Cookies и прочие.</li><li>Пересоберите и передеплойте приложение — без dotnet build/publish и повторного деплоя фикс в рантайм не попадёт.</li><li>Ротируйте DataProtection key ring. Программно — вызов IKeyManager.CreateNewKey и затем RevokeAllKeys с текущим временем. Для Redis/Azure Blob Storage — форс-ротация через управляющий интерфейс провайдера. Учтите: ротация инвалидирует активные сессии пользователей, так что готовьте сотрудников к повторному входу.</li><li>Просмотрите логи аутентификации за период с 14 по 21 апреля. Куда смотреть: Azure AD sign-in logs, ELK/Serilog-индексы с cookie-auth событиями, IIS-логи со 200-ответами на /admin-эндпоинтах. Аномалии: логины без прохождения MFA, неожиданные session-refresh, массовые password-reset-запросы.</li><li>Инвалидируйте долгоживущие секреты, выданные в окне: API-ключи, personal access tokens, refresh-токены, integration-webhooks. Если есть подозрение на компрометацию — вращайте DB-пароли и service-account-credentials.</li></ol><p>Не можете обновиться прямо сейчас? Временные меры: включите MFA на всех административных аккаунтах (это не закрывает подделку cookie, но добавляет барьер при использовании выписанных токенов), сократите срок жизни auth-cookie до минимума через ExpireTimeSpan в настройках CookieAuthenticationOptions, и форсируйте повторный вход всем пользователям через принудительный logout. Это митигация, не фикс — обновиться всё равно придётся.</p><p>Если приложение использует shared framework .NET и не тянет пакет из NuGet напрямую, уязвимость на него не распространяется. Проверяется двумя командами — dotnet --info покажет версию Microsoft.AspNetCore.App, а вторая команда подтвердит, тащит ли проект NuGet-копию:</p><h2>В каком ряду это находится</h2><p>Для ASP.NET Core это вторая серьёзная уязвимость за полгода. В октябре 2025 года Microsoft патчила <a href="https://msrc.microsoft.com/update-guide/vulnerability/CVE-2025-55315">CVE-2025-55315</a> — HTTP request smuggling в веб-сервере Kestrel с рейтингом «highest ever severity» для ASP.NET. Текущий CVE-2026-40372 бьёт в другое звено — в криптографию на уровне приложения, не веб-сервера — и открывает путь к эскалации привилегий без авторизации.</p><p>Формально Microsoft классифицирует severity как «Important», несмотря на CVSS 9,1 — внутренняя MSRC-шкала учитывает эксплуатируемость и требования к окружению, а не только CVSS-вектор. BleepingComputer и The Hacker News используют слово «critical», ориентируясь на CVSS. Публичного PoC-эксплойта пока нет, но out-of-band релиз 10.0.7 сам по себе сигнализирует, что эксплуатация считается реалистичной.</p><blockquote>Если ваше приложение использует ASP.NET Core Data Protection, обновите пакет Microsoft.AspNetCore.DataProtection до 10.0.7 как можно скорее — это закроет и регрессию дешифровки, и саму уязвимость.</blockquote><p>Если вы ведёте ASP.NET Core 10-приложение — сегодня же обновитесь до 10.0.7, передеплойтесь и ротируйте DataProtection key ring. Порядок действий — в разделе «Что делать» выше. Тянуть нельзя: атака одноходовая, а окно уже открылось.</p><p>Источники: <a href="https://www.bleepingcomputer.com/news/microsoft/microsoft-releases-emergency-security-updates-for-critical-aspnet-flaw/">BleepingComputer</a>, <a href="https://github.com/dotnet/announcements/issues/395">dotnet/announcements</a>, <a href="https://thehackernews.com/2026/04/microsoft-patches-critical-aspnet-core.html">The Hacker News</a>, <a href="https://devblogs.microsoft.com/dotnet/dotnet-10-0-7-oob-security-update/">.NET Blog</a>, <a href="https://github.com/dotnet/core/blob/main/release-notes/10.0/10.0.7/10.0.7.md">release notes 10.0.7</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Microsoft сломала localhost в Windows 11 — миллионы разработчиков не могут локально тестить проекты</title>
      <link>https://tproger.ru/news/microsoft-slomala-localhost-v-windows-11---milliony-razrabotchikov-ne-mogut-lokalno-testit-proekty</link>
      <comments>https://tproger.ru/news/microsoft-slomala-localhost-v-windows-11---milliony-razrabotchikov-ne-mogut-lokalno-testit-proekty?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Булат Яббаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/microsoft-slomala-localhost-v-windows-11---milliony-razrabotchikov-ne-mogut-lokalno-testit-proekty</guid>
      <description><![CDATA[<p>Обновление Windows 11 KB5066835 сломало localhost: HTTP.sys перестал работать, и миллионы разработчиков не могут тестировать проекты</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/microsoft-slomala-localhost-v-windows-11---milliony-razrabotchikov-ne-mogut-lokalno-testit-proekty">Microsoft сломала localhost в Windows 11 — миллионы разработчиков не могут локально тестить проекты</a>»</p>]]></description>
      <category><![CDATA[Stack Overflow]]></category>
      <category><![CDATA[Отладка]]></category>
      <category><![CDATA[.NET]]></category>
      <category><![CDATA[Windows]]></category>
      <category><![CDATA[Microsoft]]></category>
      <category><![CDATA[Windows 10]]></category>
      <category><![CDATA[Asp.NET]]></category>
      <category><![CDATA[Баги и ошибки]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Windows 11]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 17 Oct 2025 10:31:02 GMT</pubDate>
      <content:encoded><![CDATA[<p>Не прошло и двух дней после официального завершения поддержки Windows 10, как пользователи <b>Windows 11</b> <a href="https://www.techpowerup.com/341976/microsoft-breaks-localhost-with-windows-11-october-update-users-forced-to-revert">столкнулись</a> с серьезной ошибкой.</p><p>Последнее октябрьское обновление системы — <b>KB5066835</b> — нарушило работу localhost, что фактически лишило разработчиков возможности тестировать веб-приложения локально.</p><p>Проблему активно обсуждают на <b>Microsoft Support Forums</b>, <b>Stack Overflow</b> и <b>Server Fault</b>: серверы перестали отвечать на запросы, отвалилась отладка в Visual Studio, а ASP.NET-приложения не компилируются.</p><p>По оценкам экспертов, сбой затронул <b>миллионы веб-разработчиков и инженеров</b>, использующих Windows 11 в качестве локальных серверов и рабочих станций.</p><h2>Что пошло не так</h2><p>Пакет <b>KB5066835</b> был задуман как <b>обновление безопасности</b>, улучшавшее сентябрьский релиз <b>KB5065789</b>, но именно он привел к поломке <b>HTTP.sys</b> — системного компонента ядра Windows, отвечающего за маршрутизацию локального HTTP-трафика.</p><p>После установки апдейта, <b>localhost перестал отвечать на запросы</b>, а соединения по HTTP/2 начали обрываться.</p><h2>Как временно исправить</h2><p>Microsoft пока официально не подтвердила проблему, но сообщество уже нашло обходное решение:</p><ol><li>Удалить октябрьское обновление <b>KB5066835</b>.</li><li>Если не помогло — удалить и предыдущее <b>KB5065789</b>.</li><li>После этого localhost начинает работать штатно. Однако это <b>временная мера</b> и пользователи рискуют остаться без последних исправлений безопасности.</li></ol><h2>Неудачи Microsoft продолжаются</h2><p>Это уже <b>второй крупный сбой за неделю</b>. В понедельник компания случайно «сломала» <b>Media Creation Tool</b> — утилиту для установки Windows — всего за день до окончания поддержки Windows 10.</p><p>А на прошлой неделе Microsoft окончательно обязала пользователей <b>входить в Windows 11 только через онлайн-аккаунт</b>, что вызвало волну критики.</p>]]></content:encoded>
    </item>
    <item>
      <title>Состоялся релиз первого превью .NET 10: C# 14, улучшенный JIT и новые API</title>
      <link>https://tproger.ru/news/--sostoyalsya-reliz-pervogo-prevyu--net-10--c--14--uluchwennyj-jit-i-novye-api</link>
      <comments>https://tproger.ru/news/--sostoyalsya-reliz-pervogo-prevyu--net-10--c--14--uluchwennyj-jit-i-novye-api?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Булат Яббаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/--sostoyalsya-reliz-pervogo-prevyu--net-10--c--14--uluchwennyj-jit-i-novye-api</guid>
      <description><![CDATA[<p>Вышло превью .NET 10 с C# 14, улучшенным JIT и новыми API. Улучшена работа с памятью, производительность и поддержка Blazor, MAUI и ASP.NET Core</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/--sostoyalsya-reliz-pervogo-prevyu--net-10--c--14--uluchwennyj-jit-i-novye-api">Состоялся релиз первого превью .NET 10: C# 14, улучшенный JIT и новые API</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[C#]]></category>
      <category><![CDATA[.NET]]></category>
      <category><![CDATA[Microsoft]]></category>
      <category><![CDATA[Asp.NET]]></category>
      <category><![CDATA[Библиотеки]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 05 Mar 2025 04:43:13 GMT</pubDate>
      <content:encoded><![CDATA[<p><b>Microsoft представила первую превью-версию .NET 10</b>, которая принесла <b>обновленный язык C# 14</b>, значительные улучшения в JIT-компиляции и новые API.</p><p>Финальный релиз <b>ожидается в ноябре</b>, а пока разработчики могут опробовать нововведения в тестовой версии.</p><h2>C# 14: удобнее, быстрее, гибче</h2><p>В новой версии языка появились важные улучшения:</p><ul><li><b>Поддержка</b> System.Span&lt;T&gt; и System.ReadOnlySpan&lt;T&gt; на уровне языка, что делает работу с этими типами более естественной и повышает производительность без потери безопасности.</li><li><b>Упрощенная работа с дженериками</b> — теперь аргумент nameof может быть <b>непривязанным</b> (unbound) дженериком.</li><li><b>Лямбда-выражения стали гибче</b>: можно добавлять модификаторы параметров (scoped, ref, in, out, ref readonly) <b>без указания их типов</b>.</li></ul><p>Эти нововведения позволяют писать более <b>эффективный и компактный код</b> без потери производительности.</p><h2>Улучшенный JIT и производительность .NET 10</h2><p>Разработчики продолжают снижать <b>абстрактные накладные расходы</b> популярных языковых конструкций:</p><ul><li>JIT-компилятор теперь умеет <b>де-виртуализировать</b> вызовы методов для интерфейсов массивов, что ускоряет работу с массивами.</li><li><b>Автоматическое выделение небольших массивов в стеке</b>, если они не содержат указателей на управляемую память (GC), снижает нагрузку на сборщик мусора.</li></ul><p>Благодаря этим улучшениям <b>.NET 10 стал еще быстрее</b>, а нагрузка на память уменьшилась.</p><h2>Новые API и улучшения в библиотеках</h2><p><b>В стандартные библиотеки добавлены новые API</b>, которые оптимизируют работу с текстовыми данными и 3D-графикой:</p><ul><li><b>Обработка символов</b> теперь работает с Span&lt;char&gt;, что позволяет <b>избежать лишних выделений памяти</b>.</li><li><b>Поддержка матриц левой трансформации</b>, полезная при работе с <b>3D-графикой</b>.</li><li><b>Улучшена производительность</b> ZipArchive для работы с архивами.</li></ul><p>Эти обновления направлены на <b>ускорение работы кода и снижение потребления памяти</b>.</p><h2>Обновления ASP.NET Core, Blazor и MAUI</h2><ul><li><b>ASP.NET Core</b> теперь поддерживает <b>OpenAPI 3.1</b> и <b>генерацию API-документации в формате YAML</b>.</li><li><b>Blazor</b> получил <b>подсветку синтаксиса маршрутов</b>, что упрощает разработку.</li><li><b>.NET MAUI</b> теперь поставляется <b>в виде .NET workload</b> и через <b>NuGet-пакеты</b>, что облегчает фиксацию версий и тестирование экспериментальных сборок.</li></ul><p>Также в <b>Entity Framework</b> появился <b>метод</b> LeftJoin <b>для LINQ</b>, что упрощает написание SQL-запросов.</p><p>Скачать и опробовать .NET 10 можно перейдя по <a href="https://dotnet.microsoft.com/en-us/download/dotnet/10.0">ссылке</a> на официальный сайт Microsoft.</p>]]></content:encoded>
    </item>
    <item>
      <title>Как не сломать прод: настройка CORS и заголовков безопасности в ASP.NET</title>
      <link>https://tproger.ru/articles/kak-ne-slomat-prod--nastrojka-cors-i-zagolovkov-bezopasnosti-v-asp-net</link>
      <comments>https://tproger.ru/articles/kak-ne-slomat-prod--nastrojka-cors-i-zagolovkov-bezopasnosti-v-asp-net?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Александр Береговой]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-ne-slomat-prod--nastrojka-cors-i-zagolovkov-bezopasnosti-v-asp-net</guid>
      <description><![CDATA[<p>Настраиваем CORS и заголовки безопасности в ASP.NET: защищаем API от несанкционированных запросов, XSS-атак и утечек данных. Разбираем ключевые настройки без лишней головной боли.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-ne-slomat-prod--nastrojka-cors-i-zagolovkov-bezopasnosti-v-asp-net">Как не сломать прод: настройка CORS и заголовков безопасности в ASP.NET</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[.NET]]></category>
      <category><![CDATA[Asp.NET]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 28 Feb 2025 14:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Когда речь идет о безопасности веб-приложений, настройка CORS (Cross-Origin Resource Sharing) и заголовков безопасности — один из первых шагов к защите данных и предотвращению атак. Однако ошибки в конфигурации могут привести к неприятным последствиям: от блокировки легитимных запросов до уязвимостей. Рассказываем, как грамотно настроить CORS и заголовки безопасности в ASP.NET, чтобы избежать проблем и сохранить баланс между защитой и функциональностью.</p><h2>Что такое CORS?</h2><p>Браузеры строго следят за безопасностью и запрещают кросс-доменные запросы, если они не разрешены сервером. Это называется политикой одного источника (Same-Origin Policy). Она защищает пользователей от кражи данных, но иногда мешает законным сценариям.</p><p>Например, ваше веб-приложение загружено с siteA.com, но данные хранятся на api.siteB.com. По умолчанию браузер блокирует такие запросы. Как же обойти это ограничение? Использовать <b>CORS (Cross-Origin Resource Sharing).</b></p><p>CORS — механизм, который позволяет серверу явно указывать, какие домены, схемы и порты могут запрашивать у него данные. Работает через специальные HTTP-заголовки.</p><p>Если браузер видит нестандартный запрос (например, PUT или DELETE), он сначала отправляет предварительный (preflight) запрос. Это проверка: серверу сообщают о запрашиваемом методе и заголовках, а тот решает — разрешить или запретить. Если сервер даёт добро, основной запрос выполняется.</p><p>CORS — не обходной путь, а стандарт, утверждённый W3C. Без него современные веб-приложения не могли бы безопасно взаимодействовать друг с другом.</p><h2>Какие есть источники: same-origin – different-origin</h2><p>Два адреса (URL) имеют одинаковый источник (same-origin), если они оба принадлежат одному домену.</p><p>Здесь у адресов один источник:</p><ul><li>https://test.com/index.html</li><li>https://test.com/about.html</li></ul><p>А здесь — разные:</p><ul><li>https://hello.net</li><li>https://www.hello.com/foo.html</li></ul><p>Так, если приложение обратится с адреса https://hello.net к странице https://www.hello.com/foo.html без настройки политики, то CORS запрос завершится ошибкой. Чтобы запрос обработался, мы должны сказать браузеру, что обращение к источнику https://www.hello.com  разрешено.</p><p>Пример кросс-доменного запроса: JavaScript фронтенд-код, загруженный с URL https://domain-a.com, использует метод fetch() для запроса JSON-файла с URL https://domain-b.com/data.json.</p><p>CORS поддерживает безопасные кросс-доменные запросы — это снижает риски при использовании fetch() и XMLHttpRequest. Однако CORS лишь управляет разрешёнными междоменными запросами, но не гарантирует безопасность.</p><h2>Включение CORS в ASP.Net Core приложении</h2><p>Чтобы добавить механизм CORS в ASP.NET приложение, нужно:</p><ol><li>Добавить сервисы CORS в контейнер сервисов приложения;</li><li>Включить промежуточное ПО CORS в конвейер обработки HTTP-запросов.</li></ol><p>В первом шаге необходимо вызвать метод расширения AddCors для интерфейса IServiceCollection. Он добавляет в контейнер две сущности: ICorsService и ICorsPolicyProvider.</p><p>Существует также перегруженная версия этого метода расширения, позволяющая сконфигурировать политику CORS:</p><p>Во втором шаге вызывается метод расширения UseCors определенного для интерфейса IApplicationBuilder.</p><p>Этот метод добавляет промежуточное ПО CorsMiddleware в конвейер обработки HTTP-запросов. Для UseCors есть также перегруженная версия:</p><p>Есть три способа подключения CORS:</p><ul><li>В ПО промежуточного слоя с помощью именованной политики или политики по умолчанию.</li><li>Использование маршрутизации конечных точек.</li><li>С атрибутом [EnableCors].</li></ul><p>[EnableCors] с именованной политикой обеспечивает лучший контроль в ограничении конечных точек, поддерживающих CORS.</p><h2>CORS с именованной политикой и ПО промежуточного слоя</h2><p>ПО промежуточного слоя CORS обрабатывает запросы между источниками. Следующий код применяет политику CORS ко всем эндпоинтам с указанными источниками:</p><p>Пример кода выше — часть Program.cs, показывающая инициализацию WebApplication. В ней объявляется константа политики CORS — MyAllowedOrigins. Далее вызывается AddCors, в который через параметры передается имя политики и набор адресов разрешенных источников. Ниже есть вызов метода расширения UseCors, в который передано то же самое имя политики CORS.</p><p>Важно:</p><ul><li>URL в настройках CORS не должны заканчиваться на '/', иначе заголовки не вернутся.</li><li>При использовании ПО промежуточного слоя кэширования ответов (ResponseCaching) UseCors должен вызываться перед UseResponseCaching.</li><li>При использовании Endpoints настройте CORS для выполнения между вызовами UseRouting и UseEndpoints.</li><li>Обычно UseStaticFiles вызывается раньше UseCors, но если JavaScript загружает файлы, UseCors следует вызвать раньше.</li></ul><h2>CORS с политикой по умолчанию и ПО промежуточного слоя</h2><p>Следующий выделенный код включает политику CORS по умолчанию:</p><p>Разница по сравнению с предыдущим фрагментом кода в том, что здесь явно не указывается имя политики CORS. Предполагается, что она будет единственной, в то время как в предыдущем примере можно объявить несколько политик CORS, каждую со своими настройками.</p><h3>Включение CORS с маршрутизацией конечных точек</h3><p>Когда используется вызов UseEndpoints, можно подключить политику CORS к каждой отдельно взятой конечной точке, при этом можно указать имя применяемой политики в методе RequireCors:</p><p>В предыдущем коде:</p><ul><li>app.UseCors включает ПО промежуточного слоя CORS. Политики CORS привязываются к конечным точкам внутри метода UseEndpoints.</li><li>Конечные /echo точки и точки контроллера разрешают запросы между источниками с помощью указанной политики – MyAllowSpecificOrigins, переданной в RequireCors.</li><li>Конечные /echo2 точки и Razor страницы не разрешают запросы между источниками, так как политика по умолчанию не указана.</li></ul><h3>Включение CORS с помощью атрибутов</h3><p>Атрибуты [EnableCors] позволяют подключить CORS только к конечным точкам, вместо глобальной настройки через промежуточное ПО. Плюс  [EnableCors] без параметров включает политику CORS по умолчанию, а [EnableCors("{cors_policy_name}")] — именованную политику.</p><p>Атрибут [EnableCors] можно применить к:</p><ul><li>Странице Razor Page;</li><li>Контроллеру целиком;</li><li>Методам действия контроллера (Action-methods).</li></ul><p>Если CORS включён одновременно через атрибут и промежуточное ПО, применяются обе политики.</p><p>Microsoft не рекомендует смешивать способы подключения CORS. Рекомендуется в одном приложении либо применять атрибуты [EnableCors], либо использовать ПО промежуточного слоя.</p><p>Вот пример, как применить специфическую политику к каждому экшн-методу контроллера:</p><p>Здесь показано, как создать две именованные политики CORS:</p><p>Чтобы обеспечить лучшее управление ограничением CORS-запросов, стоит:</p><ul><li>применять атрибуты [EnbleCors(“{policy_name}”)] с именованной политикой;</li><li>не объявлять CORS-политику по умолчанию;</li><li>не использовать маршрутизацию конечных точек.</li></ul><h2>Как запретить CORS</h2><p>Запретить CORS для отдельных экшн-методов контроллера можно с помощью атрибута [DisableCors].</p><p>Примечание: атрибут [DisableCors] не запрещает CORS, которая была подключена при помощи методов расширения RequireCors в настройках маршрутизации конечных точек.</p><p>Пример, как запретить CORS для экшн-метода GetValues2:</p><p>Обратите внимание, что политика CORS разрешена для всего контроллера, так как контроллер декорирован атрибутом [EnableCors(“MyPolicy”)], а экшн-метод GetValues2 — [DisableCors], значит, CORS-политика не будет применена к этому методу.</p><h2>Параметры политики CORS</h2><h3>Настройка разрешенных источников</h3><p>Есть два метода расширения для указания разрешенных источников:</p><ol><li>WithOrigins — позволяет указать список разрешенных источников;</li><li>AllowAnyOrigin — разрешает CORS-запросы к любым источникам.</li></ol><p>Они влияют на заголовок Access-Control-Allow-Origin предварительных запросов.</p><h3>Настройка разрешенных HTTP методов</h3><p>Для указания разрешенных HTTP-методов есть похожая на предыдущие пара методов:</p><ol><li>WithMethods — позволяет указать список разрешенных HTTP-методов;</li><li>AllowAnyMethod — разрешает использование любых HTTP-методов в CORS-запросах.</li></ol><p>Они тоже влияют на заголовок Access-Control-Allow-Methods preflight-запросов.</p><h3>Настройка разрешенных HTTP-заголовков</h3><p>Для указания разрешённых HTTP-заголовков используются:</p><ul><li>WithHeaders — задаёт список разрешённых заголовков,</li><li>AllowAnyHeader — разрешает любые заголовки.</li></ul><p>AllowAnyHeader влияет на preflight-запросы и заголовок Access-Control-Request-Headers. Если заголовок не разрешён в WithHeaders, запрос будет отклонён. Если сервер вернёт 200 OK, но без CORS-заголовков, браузер заблокирует cross-origin запрос.</p><h3>Настройка доступных заголовков ответов</h3><p>По умолчанию браузер не предоставляет все заголовки ответов приложениям. По умолчанию предоставляются только:</p><ul><li>Cache-Control</li><li>Content-Language</li><li>Content-Type</li><li>Expires</li><li>Last-Modified</li><li>Pragma</li></ul><p>В спецификации CORS эти заголовки называются simple response headers. Чтобы сделать другие заголовки доступными для приложения, вызовите метод расширения WithExposedHeaders, передав массив имен заголовков в качестве параметра:</p><h2>Передача учетных данных в запросах между источниками</h2><p>В CORS-запросах учетные данные нужно специально обрабатывать. Речь идет о cookie и схемах аутентификации HTTP. Чтобы отправить учетные данные в CORS-запросе, клиент должен выставить свойство XMLHttpRequest.withCredentials в значение true.</p><p>Пример использования XMLHttpRequest напрямую в коде JavaScript:</p><p>Пример использования Fetch API:</p><p>Сервер должен разрешить передачу учетных данных. Чтобы это сделать, вызовите метод расширения AllowCredentials:</p><p>В результате появится заголовок Access-Control-Allow-Credentials в ответе сервера, значит, он разрешил передачу данных. Если в ответе не будет этого заголовка, то браузер не предоставит ответ, и CORS-запрос завершится ошибкой.</p><p>Включение учетных данных в CORS-запросы — риск нарушения безопасности. Web-сайт из другого домена может отправить учетные данные аутентифицированного пользователя приложению от имени этого пользователя, но без его ведома.</p><p>Спецификация CORS также говорит, что при использовании заголовков Access-Control-Allow-Credentials нельзя применять вызов AllowAnyOrigin при создании политики CORS.</p><h2>Предварительные (preflight) запросы</h2><p>Для некоторых CORS-запросов браузер отправляет preflight-запрос с HTTP-методом OPTIONS перед отправкой самого CORS. Браузер может не отправлять предварительный запрос в этих случаях:</p><ul><li>HTTP-метод основного CORS-запроса один из GET, HEAD или POST;</li><li>Приложение не добавляет в запрос заголовки, кроме Accept, Accept-Language, Content-Language, Content-Type, Last-Event-ID;</li><li>Запрос содержит заголовок Content-Type, то у него должно быть одно из значений: application/x-www-form-urlencoded, multipart/form-data, text/plain</li></ul><p>Эти правила применяются к авторским заголовкам, которые задаются вызовом setRequestHeader объекта XMLHttpRequest. С User-Agent, Host, или Content-Length (заголовками браузера) так не работает.</p><p>У Preflight-запроса могут быть такие заголовки:</p><ul><li>Access-Control-Request-Method — HTTP-метод ( в основном CORS-запросе);</li><li>Access-Control-Request-Headers — набор заголовков, которые будут установлены приложением в основном запросе.</li></ul><p>Если предварительный запрос отклоняется сервером, то вылезет код 200 ОК, и браузер не будет пытаться отправлять CORS. При отладке в браузере (F12 tools) в консоли приложения появятся ошибки, если preflight-запрос отклонится сервером.</p><p>Чтобы разрешить передачу только определенных заголовков, вызывайте WithHeaders:</p><p>Чтобы разрешить передачу всех авторских заголовков, используйте вызов AllowAnyHeader.</p><h2>Автоматическая обработка предварительных запросов</h2><p>Если политика CORS применяется с помощью одного из приведенных ниже способов:</p><ul><li>глобально, с помощью вызова app.UseCors в модуле Program.cs;</li><li>с помощью атрибута [EnableCors],</li></ul><p>то ASP.NET будет автоматически обрабатывать запросы OPTIONS.</p><h3>Обработка предварительных запросов с помощью атрибута [HttpOptions]</h3><p>В ASP.NET предусмотрена возможность явного объявления методов для обработки предварительных запросов. Вот пример, как создать методы для обработки OPTIONS-запросов с [HttpOptions]:</p><h3>Установка срока действия ответов для предварительных запросов</h3><p>Браузер может закэшировать preflight-запросы, чтобы снизить нагрузку на сервер и сократить время обработки основных CORS-запросов. Чтобы ограничить срок хранения ответов в кэше, используйте заголовок Access-Control-Max-Age в ответе prefligh-запроса. Для этого при инициализации CORS-политики вызовите метод SetPreflightMaxAge:</p><p>CORS позволяет обращаться к ресурсам на других доменах, но требует аккуратной настройки, чтобы не сломать безопасность.</p><p>В примерах выше CORS-политики определялись в коде приложения, но в проде такой подход не всегда удобен. При переносе на другой хостинг или смене окружения настройки лучше вынести в конфигурацию сервера или прокси. Это упростит поддержку и адаптацию без правок в коде.</p><h3>Полезные ссылки</h3><p><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS">Cross-Origin Resource Sharing (CORS) - HTTP | MDN</a></p><p><a href="https://learn.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-9.0">Enable Cross-Origin Requests (CORS) in ASP.NET Core | Microsoft Learn</a></p><p>Больше про .NET — в нашем <a href="https://t.me/+L9Wi95tNHhs1MTIy">тг канале</a>!</p>]]></content:encoded>
    </item>
    <item>
      <title>Работа с конфигурацией в ASP.NET Core: практическое руководство с настройками MongoDB</title>
      <link>https://tproger.ru/articles/rabota-s-konfiguraciej-v-asp-net-core--prakticheskoe-rukovodstvo-s-nastrojkami-mongodb-251910</link>
      <comments>https://tproger.ru/articles/rabota-s-konfiguraciej-v-asp-net-core--prakticheskoe-rukovodstvo-s-nastrojkami-mongodb-251910?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Ponomareff]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/rabota-s-konfiguraciej-v-asp-net-core--prakticheskoe-rukovodstvo-s-nastrojkami-mongodb-251910</guid>
      <description><![CDATA[<p>MongoDB — популярная NoSQL база данных, которая хранит данные в формате документов. В статье расскажем, как настроить конфигурацию в ASP.NET Core с использованием паттерна Options.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/rabota-s-konfiguraciej-v-asp-net-core--prakticheskoe-rukovodstvo-s-nastrojkami-mongodb-251910">Работа с конфигурацией в ASP.NET Core: практическое руководство с настройками MongoDB</a>»</p>]]></description>
      <category><![CDATA[Asp.NET]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 20 Sep 2024 09:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>В ASP.NET Core система конфигурации гибкая и позволяет управлять различными настройками приложения, такими как подключение к базе данных, API-ключи и другие параметры конфигурации. В этой статье мы рассмотрим настройку и управление параметрами конфигурации в приложении ASP.NET Core, используя класс MongoSettings в качестве примера. Мы будем использовать паттерн Options (Опции), который является рекомендуемым способом для доступа к строго типизированным настройкам.</p><h2>Почему важна конфигурация</h2><p>Конфигурация в приложениях ASP.NET Core необходима для управления различными средами (разработка, продакшн и т.д.), выноса чувствительной информации, такой как строки подключения, и делает ваше приложение более гибким и поддерживаемым. ASP.NET Core поддерживает конфигурации из различных источников, таких как JSON-файлы (appsettings.json), переменные окружения и другие.</p><h2>Настройка MongoDB</h2><p>Начнем с определения подключения к MongoDB, а затем посмотрим, как оно интегрируется в систему конфигурации ASP.NET Core.</p><h3>Шаг 1: Определение класса MongoSettings</h3><p>Начнем с создания строго типизированного класса конфигурации, MongoSettings, который будет хранить параметры подключения к MongoDB.</p><p>Этот класс включает такие свойства, как ConnectionString, Database, RabbitMessagesCollectionName и MetricsCollectionName, все из которых отмечены как обязательные с помощью аннотаций данных.</p><h3>Шаг 2: Добавление конфигурации в appsettings.json</h3><p>Пустой пример настроек — это пример раздела конфигурации MongoDB, где еще не указаны никакие значения. Он представляет собой шаблон, который следует заполнить:</p><p>Файл appsettings.json является основным источником конфигурации в ASP.NET Core. Вот пример того, как настройки MongoDB могут выглядеть в appsettings.json.</p><p>Здесь мы определяем раздел MongoConnection, который соответствует структуре нашего класса MongoSettings. Это позволяет фреймворку автоматически сопоставить структуру JSON с нашим классом.</p><h3>Шаг 3: Настройка сервисов в Program.cs</h3><p>Чтобы привязать конфигурацию из appsettings.json к нашему классу MongoSettings, мы используем методы Configure и AddOptions в Program.</p><p>С помощью services.Configure() фреймворк привязывает раздел MongoConnection из appsettings.json к классу MongoSettings. Это позволяет вам получить доступ к этим настройкам позже в приложении.</p><h3>Шаг 4: Доступ к настройкам конфигурации</h3><p>После настройки конфигурации вы можете внедрить IOptionsв в любой сервис или контроллер, где вам необходим доступ к настройкам MongoDB.</p><p>В приведенном примере мы внедряем IOptions в конструктор MyMongoService и получаем доступ к настройкам через свойство .Value. Паттерн IOptions гарантирует, что ваша конфигурация строго типизирована и проверена на старте.</p><h3>Шаг 5: Валидация конфигурации</h3><p>ASP.NET Core поддерживает валидацию параметров конфигурации, чтобы убедиться, что все обязательные поля заданы корректно до запуска приложения. Вы можете добавить валидацию с помощью метода ValidateOnStart при настройке опций.</p><p>Здесь мы вызываем ValidateDataAnnotations для проверки аннотаций данных в классе MongoSettings (таких как [Required] и [Url]). ValidateOnStart гарантирует, что конфигурация проверяется при запуске приложения, предотвращая ошибки во время выполнения.</p><h2>Заключение</h2><p>Управление конфигурацией — это важный аспект приложений ASP.NET Core. Использование строго типизированных классов и паттерна Options обеспечивает чистый, поддерживаемый и гибкий способ работы с настройками, такими как подключения к базам данных. В этом примере мы продемонстрировали, как настроить и использовать MongoSettings в приложении ASP.NET Core, но этот же паттерн применим к любому разделу конфигурации.</p><p>Используя валидацию и правильную обработку конфигурации, вы можете обеспечить надежность и стабильность своего приложения в различных средах.</p><h2>Дополнительные материалы</h2><p>Чтобы узнать побольше о конфигурации и паттерне Options в ASP.NET Core ознакомьтесь с официальной документацией:</p><ul><li><a href="https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-8.0">Конфигурация в ASP.NET Core</a></li><li><a href="https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/options?view=aspnetcore-8.0">Паттерн Options в ASP.NET Core</a></li></ul>]]></content:encoded>
    </item>
    <item>
      <title>Сайт на ASP.NET для начинающих — первые шаги</title>
      <link>https://tproger.ru/articles/web-asp-net-for-beginners</link>
      <comments>https://tproger.ru/articles/web-asp-net-for-beginners?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Александр Ланский]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/web-asp-net-for-beginners</guid>
      <description><![CDATA[<p>Платформа Microsoft используется примерно на 2 000 000 сайтов по данным SimilarTech. Вводный курс по созданию проекта на ASP.NET в Visual Studio.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/web-asp-net-for-beginners">Сайт на ASP.NET для начинающих — первые шаги</a>»</p>]]></description>
      <category><![CDATA[Для начинающих]]></category>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[C#]]></category>
      <category><![CDATA[Asp.NET]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 15 Oct 2020 13:20:52 GMT</pubDate>
      <content:encoded><![CDATA[<p><a href="https://dotnet.microsoft.com/apps/aspnet">ASP.NET</a> — платформа от Microsoft для создания и развёртывания сайтов, веб-приложений и сервисов. <a href="https://www.similartech.com/technologies/asp-net">По данным SimilarTech</a>, около 2 000 000 сайтов используют эту платформу. В этой статье описаны первые шаги создания сайта на ASP.NET.</p><p>Для разработки будем использовать Visual Studio.</p><h2>Создание ASP.NET проекта</h2><p>Откройте Visual Studio Installer и нажмите «Изменить» на нужной среде разработки. Перед вами откроется список всех нагрузок. В категории Веб-разработка и облако нужно включить ASP.NET и разработка веб-приложений. После этого нажмите на кнопку Изменить в нижнем правом углу и дождитесь установки нагрузки.</p><figure><img src="https://media.tproger.ru/uploads/2020/10/asp.net-download.png" alt="" /></figure><p>Перейдите в Visual Studio и создайте новый проект, выбрав тип Веб-приложение ASP.NET (.NET Framework). Потом нужно выбрать необходимую модель приложения:</p><ul><li>Веб-формы — можно легко создавать динамические веб-сайты, используя сотни элементов управления и компонентов.</li><li>MVC — эффективный, основанный на шаблонах способ создания динамических сайтов. Предоставляет полный контроль над разметкой для гибкой разработки.</li><li>Веб-API — позволяет легко создавать HTTP службы для широкого диапазона клиентов. Идеальная платформа для сборки REST-приложений.</li><li>Приложение SPA — одностраничное веб-приложение, которое загружает HTML-страницу и динамически обновляет её при взаимодействии с пользователем.</li></ul><p>Выберете модель Веб-формы и завершите создание проекта.</p><h2>Внутренняя структура проекта</h2><p>В проекте сайта уже загружены некоторые библиотеки, необходимые для комфортного старта: CSS-фреймворк Bootstrap, JS-фреймворк jQuery, MSAjax и некоторые другие.</p><p>После создания тут уже присутствуют 3 страницы: Default, About и Contact. Каждая страница состоит из 3 файлов:</p><ul><li>Page.aspx — содержит в себе HTML-разметку конкретной страницы;</li><li>Page.aspx.cs — отвечает за логику работы конкретной страницы;</li><li>Page.aspx.designer.cs — является мостом между Page.aspx и Page.aspx.cs.</li></ul><p>Вот так выглядит About.aspx:</p><p>Как видно, этот файл содержит лишь контент конкретной страницы. Вся общая разметка находится в Site.Master и Site.Mobile.Master.</p><p>Чтобы проверить и запустить проект, нажмите IIS Express или же традиционную клавишу F5. После этого все файлы скомпилируются и сайт откроется по адресу http://localhost:4400 в браузере по умолчанию. Номер порта может отличаться.</p><figure><img src="https://media.tproger.ru/uploads/2020/10/asp-mainpage.png" alt="" /></figure><h2>Создание веб-формы</h2><p>Чтобы создать новую страницу, в контекстном меню проекта выберите Добавить→Веб-форма. После этого автоматически сгенерируются и заполнятся все 3 файла.</p><p>Примечание Веб-формы можно создавать с помощью встроенного графического конструктора веб-форм. Что бы открыть его, в контекстном меню нужной веб-формы нажмите на Открыть в конструкторе. Все необходимые элементы можно достать из Панели Элементов (Вид→Панель элементов). Но если вам нужна максимальная гибкость и функциональность — лучше разрабатывать формы вручную в коде.</p><p>Потом можно добавить ссылку на новую страницу в панель навигации в Site.Master:</p><p>Примечание Обратите внимание, что в ссылке указывается название страницы без расширения.</p><p>Если вы откроете новую страницу, то заметите, что вся общая вёрстка отсутствует. Это потому, что в новой странице не подвязывается разметка из Site.Master. Чтобы исправить это, нужно в новой форме вместо сгенерированной вёрстки вставить это:</p><p>Во всех упоминаниях нужно заменить News на название вашей страницы. Теперь форма будет отображаться вместе с общей вёрсткой.</p><p>Для интеграции значений в вёрстку из aspx.cs используют специальный тег &lt;%: %&gt;:</p><p>В этом случае SomeVar должен быть публичным полем. Если нужно выполнить какой-либо код для присвоения значения этой переменной, то выполнить его нужно в сгенерированном методе Page_Load.</p><p>Получение значений параметров из URL производится через статический класс Request, в котором хранятся и прочие данные о запросе:</p><p>Изучить все возможности веб-форм можно в <a href="https://docs.microsoft.com/ru-ru/aspnet/web-forms/">официальной документации</a>.</p><h2>Движок представлений Razor</h2><p><a href="https://docs.microsoft.com/ru-ru/aspnet/core/mvc/views/razor?view=aspnetcore-3.1">Razor</a> позволяет делать вставки C# кода прямо в HTML разметке. Для этого нужно создать отдельный файл .cshtml (Контекстное меню проекта→Добавить→Страница представления MVC 5 (Razor)). Разметка в этом файле ничем не отличается от обычной HTML-вёрстки.</p><p>По умолчанию языком Razor является HTML. Для перехода с вёрстки на C# используют символ @, а сам блок кода помещается в фигурные скобки.</p><p>В Razor также можно выполнять неявные выражения прямо в HTML разметке:</p><p>Тут есть привычные для ЯП конструкции, которые могут значительно облегчить вёрстку. Вот некоторые из них:</p><p>Также всегда будет полезным просмотр open source проектов. Там вы найдёте не только лучшие практики по ASP.NET, но и просто решение популярных задач.</p>]]></content:encoded>
    </item>
    <item>
      <title>Пишем свой первый RESTful веб-сервис на ASP.NET</title>
      <link>https://tproger.ru/translations/restful-service-asp-net</link>
      <comments>https://tproger.ru/translations/restful-service-asp-net?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Никита Прияцелюк]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/translations/restful-service-asp-net</guid>
      <description><![CDATA[<p>REST на базе HTTP используют для лёгких, поддерживаемых и масштабируемых веб-сервисов; на ASP.NET такой сервис можно собрать самостоятельно.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/translations/restful-service-asp-net">Пишем свой первый RESTful веб-сервис на ASP.NET</a>»</p>]]></description>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[C#]]></category>
      <category><![CDATA[Asp.NET]]></category>
      <category><![CDATA[Переводы]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 31 Oct 2018 17:06:46 GMT</pubDate>
      <content:encoded><![CDATA[<h2>Что такое RESTful веб-сервис?</h2><p>REST используется для создания легковесных, поддерживаемых и масштабируемых веб-сервисов. Сервис, построенный на REST архитектуре, называется RESTful-сервисом. REST использует HTTP — базовый сетевой протокол.</p><p>Далее в статье:</p><ul><li><a href="https://tproger.ru/#1">Ключевые составляющие RESTful</a></li><li><a href="https://tproger.ru/#2">Методы RESTful</a></li><li><a href="https://tproger.ru/#3">Почему RESTful</a></li><li><a href="https://tproger.ru/#4">RESTful архитектура</a></li><li><a href="https://tproger.ru/#5">Принципы и ограничения RESTful</a></li><li><a href="https://tproger.ru/#6">Создаём свой первый RESTful веб-сервис с ASP.NET</a></li><li><a href="https://tproger.ru/#7">Запускаем наш веб-сервис</a></li><li><a href="https://tproger.ru/#8">Тестируем веб-сервис</a></li></ul><h2>Ключевые составляющие RESTful</h2><p>Веб-сервисы прошли долгий путь с момента их появления. В 2002 году <a href="https://ru.wikipedia.org/wiki/Консорциум_Всемирной_паутины">W3C</a> выпустил определения WSDL и SOAP веб-сервисов. Это сформировало стандарт по созданию веб-сервисов.</p><p>В 2004 году W3C выпустил определение ещё одного стандарта под названием RESTful. В последние годы этот стандарт стал довольно популярным. На данный момент он используется многими известными сайтами по всему миру, в число которых входит и Twitter.</p><p>REST — это способ получить доступ к ресурсам, которые находятся в определённой среде. Например, у вас может быть сервер с важными документами или фотографиями. Всё это — ресурсы. Если клиенту, скажем, веб-браузеру, нужны какие-то из этих ресурсов, ему необходимо отправить запрос на сервер для получения доступа к ним. REST определяет, как может осуществляться доступ к этим ресурсам.</p><p>Ключевые составляющие реализации RESTful:</p><ol><li>Ресурсы. Допустим, у нас есть сервер с записями о сотрудниках, а адрес веб-приложения — http://server.com. Чтобы получить доступ к записи сотрудника, мы можем выполнить команду http://server.com/employee/1, которая говорит серверу предоставить запись сотрудника под номером 1.</li><li>Методы запросов. Они говорят, что вы хотите сделать с ресурсом. Браузер использует метод GET, чтобы проинформировать удалённую сторону о том, что он хочет получить данные. Кроме GET есть много других методов вроде POST, PUT и DELETE. В примере с http://server.com/employee/1 выше браузер на самом деле использует метод GET, поскольку он хочет получить данные о сотруднике.</li><li>Заголовки запроса. Это дополнительные инструкции, посылаемые вместе с запросом. Они могут определять тип необходимого ресурса или подробности авторизации.</li><li>Тело запроса. Это данные, отправляемые вместе с запросом. Данные обычно отправляются, когда выполняется POST-запрос к REST веб-сервису. Зачастую в POST-запросе клиент говорит серверу, что он хочет добавить на него ресурс. Следовательно, тело запроса содержит подробную информацию о ресурсе, который необходимо добавить на сервер.</li><li>Тело ответа. Это основная часть ответа. В нашем примере на запрос http://server.com/employee/1 сервер мог бы прислать XML-документ с данными о сотруднике в теле ответа.</li><li>Коды ответа. Эти коды возвращаются сервером вместе с ответом. Например, код 200 обычно означает, что при отправке ответа не произошло никакой ошибки.</li></ol><h2>Методы RESTful</h2><p>Представим, что у нас есть RESTful веб-сервис по адресу http://server.com/employee/. Когда клиент делает запрос к нему, он может  указать любой из обычных HTTP-методов вроде GET, POST, DELETE и PUT. Ниже указано, что могло бы произойти при использовании соответствующего метода:</p><ul><li>POST — с его помощью можно создать новую запись сотрудника;</li><li>GET — с его помощью можно запросить список сотрудников;</li><li>PUT — с его помощью можно обновить данные сотрудников;</li><li>DELETE — с его помощью можно удалять записи сотрудников.</li></ul><p>Посмотрим на это с точки зрения одной записи. Допустим у нас есть запись сотрудника под номером 1. Вот какое значение могли бы иметь следующие действия:</p><ul><li>POST — этот метод нельзя применить, так как сотрудник с номером 1 уже существует;</li><li>GET — этот метод можно использовать для получения данных о сотруднике под номером 1;</li><li>PUT — этот метод можно использовать для обновления данных сотрудника под номером 1;</li><li>DELETE — этот метод можно использовать для удаления записи сотрудника под номером 1.</li></ul><h2>Почему RESTful</h2><p>В основном популярность RESTful обусловлена следующими причинами:</p><p>1. Разнородные языки и среды — это одна из основных причин:</p><ul><li>У веб-приложений, написанных на разных языках, есть возможность взаимодействовать друг с другом;</li><li>Благодаря RESTful эти приложения могут находиться в разных средах, будь то Windows или Linux.</li></ul><p>Представим, что для работы с такими сайтами как Twitter, Google и т. д. клиентскому приложению нужно знать, на каких языках и на какой платформе они написаны. Основываясь на этих знаниях, мы могли бы написать код для взаимодействия с ними, однако это превратилось бы в сущий ад.</p><p>Twitter и Google дают доступ к их функциональности посредством RESTful веб-сервисов. Это даёт возможность любому клиентскому приложению взаимодействовать с этими сервисами с помощью REST.</p><p><b>2. Технологический бум</b> – сегодня всё должно работать на разнообразных устройствах, будь то смартфон, ноутбук или кофеварка. Представляете, каких бы усилий стоило наладить взаимодействие этих устройств с помощью обычных веб-приложений? RESTful API делают эту задачу гораздо проще, поскольку, как было упомянуто выше, вам не нужно знать, что у устройства «под капотом».</p><p>3. Появление облачных сервисов — всё переезжает в облако. Приложения медленно перемещаются в облачные системы вроде Azure или Amazon, которые предоставляют большое количество API на основе RESTful архитектуры. Следовательно, приложения должны разрабатываться таким образом, чтобы они были совместимы с облаком. Так как все облачные архитектуры работают на основе REST, логично разрабатывать веб-сервисы тоже на REST-архитектуре, чтобы извлечь максимум пользы из облачных сервисов.</p><h2>RESTful архитектура</h2><p>Приложение или архитектура считается RESTful, если ей присущи следующие характеристики:</p><ol><li>Состояние и функциональность представлены в виде ресурсов — это значит, что каждый ресурс должен быть доступен через обычные HTTP-запросы GET, POST, PUT или DELETE. Так, если кто-то хочет получить файл на сервере, у них должна быть возможность отправить GET-запрос и получить файл. Если он хочет загрузить файл на сервер, то у него должна быть возможность использовать POST или PUT-запрос. Наконец, если он хочет удалить файл, должна быть возможность отправить запрос DELETE.</li><li>Архитектура клиент-сервер, отсутствие состояния (stateless) и поддержка кеширования:Клиент-сервер — обычная архитектура, где сервером может быть веб-сервер, на котором размещено приложение, а клиентом — обычный веб-браузер;Архитектура без сохранения состояния означает, что состояние приложения не сохраняется в REST. Например, если вы удалили ресурс с сервера командой DELETE, то даже при получении положительного кода ответа нет гарантий, что он действительно был удалён. Чтобы убедиться, что ресурс удалён, необходимо отправить GET-запрос. С его помощью можно запросить ресурсы, чтобы посмотреть, присутствует ли там удалённый.</li></ol><h2>Принципы и ограничения RESTful</h2><p>Архитектура REST основывается на нескольких характеристиках, которые описаны ниже. Любой RESTful веб-сервис должен им соответствовать, чтобы называться таковым. Эти характеристики также известны как принципы проектирования, которым нужно следовать при работе с RESTful-сервисами.</p><h3>RESTful клиент-сервер</h3><figure><img src="https://media.tproger.ru/user-uploads/34561/2023-12-25/9fc8e483-1b03-4332-9247-881492952d68.png" alt="" /></figure><p>Это самое важное требование REST-архитектуры. Оно означает, что на сервере располагается RESTful веб-сервис, который предоставляет необходимую функциональность клиенту. При отправке клиентом запроса к веб-сервису сервер должен либо отклонить его, либо принять и предоставить соответствующий ответ.</p><h3>Отсутствие состояния</h3><p>Эта концепция означает, что задачей именно клиента является убедиться, что серверу передаются все необходимые данные. Это нужно для того, чтобы сервер мог составить ответ должным образом. Это простая независимая последовательность вопросов-ответов. Клиент задаёт вопрос, сервер отвечает соответствующим образом. Затем клиент задаёт другой вопрос, однако сервер не помнит, что было до этого, поэтому отвечает на него независимо.</p><h3>Кеш</h3><figure><img src="https://media.tproger.ru/user-uploads/34561/2023-12-25/cae95378-ba90-4bba-8075-6dbf0744f567.png" alt="" /></figure><p>Концепция кеша помогает нивелировать проблему отсутствия состояния. Так как каждый запрос клиента независим по своей природе, порой клиент может повторно отправить какой-нибудь запрос. Запрос придёт на сервер, и сервер отправит ответ. Это увеличивает сетевой трафик. Кеш позволяет клиенту хранить прежде отправленные запросы и ответы. Поэтому при повторной отправке запроса он не будет отправлен серверу; вместо этого необходимые данные будут взяты из кеша.</p><h3>Многослойная система</h3><p>Суть этой концепции заключается в том, что любой дополнительный слой вроде промежуточного (слой, в котором создаётся бизнес-логика; это может быть дополнительный сервис, с которым клиент взаимодействует до сервера) можно поместить между клиентом и сервером, на котором располагается RESTful веб-сервис. Однако этот слой должен быть внедрён прозрачно, чтобы он не нарушил взаимодействия клиента и сервера.</p><h3>Единообразие интерфейса</h3><p>Это фундаментальное требование дизайна RESTful-сервисов. RESTful работает на уровне <a href="https://tproger.ru/translations/http-api-design-guide/">HTTP</a> и использует нижеприведённые методы для работы с ресурсами на сервере:</p><ul><li>POST — для создания ресурса;</li><li>GET — для его получения;</li><li>PUT — для его обновления;</li><li>DELETE — для его удаления.</li></ul><h2>Создаём свой первый RESTful веб-сервис с ASP.NET</h2><p>Веб-сервисы можно создавать на множестве языков. Многие IDE можно использовать для создания REST-сервисов.</p><p>Мы напишем REST-приложение на .NET, используя Visual Studio.</p><p>Наш сервис будет работать со следующим набором данных «туториалов»:</p><figure><img src="https://media.tproger.ru/user-uploads/34561/2023-12-25/15e8d4d1-a4cc-4ff2-a275-5da9f3b1eff8.png" alt="" /></figure><p>Мы реализуем следующие RESTful методы:</p><ul><li>GET Tutorial — при его вызове клиент получает все доступные TutorialName;</li><li>GET Tutorial/TutorialId — при его вызове клиент получает TutorialName, соответствующее переданному TutorialId;</li><li>POST Tutorial/TutorialName — при его вызове клиент отправляет запрос на добавление туториала с переданным TutorialName;</li><li>DELETE Tutorial/TutorialId — при его вызове клиент отправляет запрос на удаление туториала с TutorialName, соответствующему переданному TutorialId.</li></ul><p>Теперь создадим шаг за шагом наш веб-сервис.</p><p><b>Шаг первый</b></p><p>Нам нужно создать пустое ASP.NET веб-приложение. Для этого откройте Visual Studio и создайте новый проект:</p><figure><img src="https://media.tproger.ru/user-uploads/34561/2023-12-25/a68a24df-1005-4414-a46b-590b933953cd.png" alt="" /></figure><p><a href="https://media.tproger.ru/uploads/2018/10/vs1.png"></a></p><p>После выбора этой опции должно появиться новое диалоговое окно, о котором мы поговорим в следующем шаге.</p><p><b>Шаг второй</b></p><p>В открывшемся окне перейдите по вкладкам C# → Веб. Выберите опцию «Веб-приложение ASP.NET (.NET Framework)» и введите необходимые данные проекта вроде названия и каталога:</p><figure><img src="https://media.tproger.ru/user-uploads/34561/2023-12-25/ed207d6a-7d23-4c26-a37a-d969670db893.png" alt="" /></figure><p>Если далее у вас появилось следующее окно, выбирайте вариант «Пустой»:</p><figure><img src="https://media.tproger.ru/user-uploads/34561/2023-12-25/ca96dd27-787d-419e-8c30-ea8916de93c4.png" alt="" /></figure><p><a href="https://media.tproger.ru/uploads/2018/10/vs3.png"></a></p><p>После этого должно открыться окно, где в обозревателе решений можно увидеть наш проект:</p><figure><img src="https://media.tproger.ru/user-uploads/34561/2023-12-25/555f868e-ea9d-49bf-b691-cc45b464460f.png" alt="" /></figure><p><a href="https://media.tproger.ru/uploads/2018/10/vs4.png"></a></p><p><b>Шаг третий</b></p><p>Теперь нужно создать файл нашего RESTful веб-сервиса. Для этого сначала нажмите Ctrl+Shift+A, либо кликните правой кнопкой по файлу проекта Webservice.REST и выберите опции Добавить → Создать элемент…:</p><figure><img src="https://media.tproger.ru/user-uploads/34561/2023-12-25/118f758d-390b-40c8-a0da-58c4b656b526.png" alt="" /></figure><p>В открывшемся окне найдите опцию «Служба WCF (с поддержкой технологии AJAX)» и дайте ей имя TutorialSevice.svc:</p><figure><img src="https://media.tproger.ru/user-uploads/34561/2023-12-25/7575ac5b-8a17-4259-b2fd-1442457b9b20.png" alt="" /></figure><p><a href="https://media.tproger.ru/uploads/2018/10/vs6.png"></a></p><p>Прим. перев. Если вы не можете найти эту опцию, то попробуйте открыть Visual Studio Installer и загрузить часть среды, ответственную за работу с ASP.NET:</p><figure><img src="https://media.tproger.ru/user-uploads/34561/2023-12-25/eaebef51-b485-4285-b2f9-97e6acce2890.png" alt="" /></figure><p>После выбора опции «Служба WCF (с поддержкой технологии AJAX)» Visual Studio создаст код, который будет основой для реализации веб-сервиса. WCF (Windows Communication Foundation) — библиотека, необходимая для налаживания взаимодействия между приложениями с помощью разных протоколов вроде TCP, HTTP и HTTPS. <a href="https://ru.wikipedia.org/wiki/AJAX">AJAX</a> позволяет асинхронно обновлять веб-страницы, обмениваясь небольшими объёмами информации с сервером.</p><p><b>Шаг четвёртый</b></p><p>Теперь нам нужно внести изменения в конфигурационный файл Web.config. Он содержит настройки, необходимые для правильной работы приложения. Наше изменение позволит приложению отправлять и принимать данные как RESTful веб-сервис.</p><p>Откройте конфигурационный файл:</p><figure><img src="https://media.tproger.ru/user-uploads/34561/2023-12-25/e3ff9952-bba9-4bf0-853c-83b65b985ade.png" alt="" /></figure><p><a href="https://media.tproger.ru/uploads/2018/10/vs8.png"></a></p><p>В открывшемся файле найдите строку &lt;enableWebScript /&gt; и замените её на &lt;webHttp /&gt;.</p><p><b>Шаг пятый</b></p><p>Пора приниматься за код. Откройте файл TutorialService.svc. Сначала добавим код для отображения наших данных. Создадим список со строками «Arrays», «Queues» и «Stacks». Они будут отражать имена доступных туториалов:</p><p><b>Шаг шестой</b></p><p>Теперь напишем код для нашего метода GET в том же файле. Этот метод будет запускаться при каждом вызове сервиса из браузера. Он будет использоваться для получения доступных туториалов:</p><p>Строка [WebGet(UriTemplate="/Tutorial")] — самая важная. Она нужна для определения того, как мы будем вызывать этот метод по URL. Если наш сервис расположен по адресу http://localhost:52645/TutorialService.svc и в его конец мы добавим «/Tutorial» и получим http://localhost:52645/TutorialService.svc/Tutorial, то будет вызван вышеприведённый код. Атрибут WebGet является параметром, который позволяет GetAllTutorials() быть RESTful-методом, который можно вызвать GET-запросом.</p><p>В самом методе GetAllTutorials() находится код, который собирает все названия туториалов и возвращает их в одной строке.</p><p><b>Шаг седьмой</b></p><p>Код, показанный ниже, нужен для того, чтобы вернуть соответствующий TutorialName при получении GET-запроса с TutorialId:</p><p>Как и в предыдущем примере, первая строка — самая важная, так как определяет то, как мы будем вызывать этот метод. Если мы сделаем запрос http://localhost:52645/TutorialService.svc/Tutorial/1, то веб-сервис должен вернуть TutorialName, соответствующий TutorialId с индексом 1.</p><p>Метод GetTutorialByID() реализует описанную логику. Обратите внимание на то, что мы приводим TutorialId к типу Integer. Это связано с тем, что всё передаваемое в адресную строку браузера является строкой. А поскольку индексом списка не может быть строка, мы добавляем код, необходимый для преобразования в число.</p><p><b>Шаг восьмой</b></p><p>Настала очередь кода для метода POST, который будет вызываться каждый раз, когда мы захотим добавить строку в наш список туториалов с помощью POST-запроса:</p><p>На первой строке находится атрибут WebInvoke, прикреплённый к нашему методу, что позволяет вызывать его с помощью POST-запроса. Для атрибутов RequestFormat и ResponseFormat мы указываем JSON, так как именно с этим форматом работает RESTful веб-сервис.</p><p><b>Шаг девятый</b></p><p>Осталось добавить метод для работы с DELETE-запросами. Он будет вызываться каждый раз, когда мы будем пытаться удалить существующее значение из списка с помощью DELETE-запроса:</p><p>Первая-вторая строки ничем особо не отличаются от предыдущих методов, они сигнализируют о том, что нижеуказанный метод будет вызываться при каждом DELETE-запросе.</p><p>В самом методе DeleteTutorial()  мы приводим переданный TutorialId к типу Integer и удаляем из списка соответствующий элемент.</p><p>В итоге код должен выглядеть так (не учитывая элементов, которые были там изначально):</p><h2>Запускаем наш веб-сервис</h2><p>Мы создали наш веб-сервис, пора его запустить.</p><p>Сначала кликните правой кнопкой по файлу проекта Webservice.REST и выберите опцию «Назначить автозагружаемым проектом», чтобы Visual Studio запустила этот проект при запуске всего решения:</p><figure><img src="https://media.tproger.ru/user-uploads/34561/2023-12-25/2934ce54-54f5-4fab-8e39-5bf793e610c6.png" alt="" /></figure><p>Теперь осталось запустить проект. Рядом с кнопкой запуска будет указано имя браузера, в котором будет запускаться проект. Автоматически будет предложен браузер по умолчанию, однако вам ничто не мешает выбрать другой:</p><figure><img src="https://media.tproger.ru/user-uploads/34561/2023-12-25/864a1f27-0dfb-43d6-8856-f4f67cc65046.png" alt="" /></figure><p>После запуска должно открыться окно браузера. Перейдите по адресу http://localhost:51056/TutorialService.svc/Tutorial и в зависимости от выбранного браузера вы увидите что-то такое:</p><figure><img src="https://media.tproger.ru/user-uploads/34561/2023-12-25/4fff5611-cacb-4ffc-a8cf-c208c6c64600.png" alt="" /></figure><p><a href="https://media.tproger.ru/uploads/2018/10/vs11.png"></a></p><p>Прим. перев. В вашем случае сервис может запуститься на localhost с другим портом. Далее в статье мы будем использовать значение 51056, однако не забывайте заменять его на своё, когда будете пытаться запускать примеры.</p><p>В этом примере браузер делает GET-запрос и тем самым вызывает написанный нами метод GetAllTutorials(), который возвращает список со всеми туториалами.</p><h2>Тестируем веб-сервис</h2><p>Выше мы увидели, как браузер делает GET-запрос для вызова GetAllTutorials(). Давайте проверим другие сценарии.</p><p>1. GET Tutorial/TutorialId — при вызове этого RESTful API клиент должен получить TutorialName, соответствующий переданному TutorialId.</p><p>Для вызова просто добавьте строку «/1» в конце URL, чтобы получить http://localhost:51056/TutorialService.svc/Tutorial/1. После перехода по этой ссылке вы должны увидеть следующее:</p><figure><img src="https://media.tproger.ru/user-uploads/34561/2023-12-25/53da75ff-f3dd-476f-aabe-8c281d3acedf.png" alt="" /></figure><p>В этот раз был вызван метод GetTutorialByID(), который вернул туториал с индексом 1 — «Queues».</p><p>2. POST Tutorial/TutorialName — при вызове этого API клиент отправляет запрос на добавление переданного TutorialName, который сервер должен добавить в список. В этот раз нам понадобится инструмент Fiddler, который можно бесплатно скачать с <a href="https://www.telerik.com/download/fiddler">официального сайта</a>.</p><p>Запустите Fiddler и выполните следующие действия:</p><ol><li>Переключитесь на вкладку Composer. Она используется для создания запросов, которые можно отравить любому веб-приложению;</li><li>Установите тип запроса равным «POST», а в URL вставьте адрес сервиса, в нашем случае это http://localhost:51056/TutorialService.svc/Tutorial;</li><li>В окне, где уже есть строка «User-Agent: Fiddler» добавьте строку «Content-Type: application/json». Наш сервис работает только с данными в формате JSON, помните?</li><li>Осталось ввести данные в поле «Request Body». Наш метод для POST-запросов принимает параметр str. Передавая строку {"str": "Trees"}, мы указываем, что хотим добавить в список значение «Trees».</li></ol><figure><img src="https://media.tproger.ru/user-uploads/34561/2023-12-25/de034be7-c168-4977-b000-c729349b2953.png" alt="" /></figure><p>Нажмите на кнопку «Execute». После этого нашему сервису будет отправлен запрос на добавление «Trees».</p><p>Чтобы убедиться, что всё прошло как надо, получим список всех туториалов, перейдя по ссылке http://localhost:51056/TutorialService.svc/Tutorial. Вы должны увидеть следующее:</p><figure><img src="https://media.tproger.ru/user-uploads/34561/2023-12-25/3286b560-3817-4189-ba11-3a72ff0809d9.png" alt="" /></figure><p><a href="https://media.tproger.ru/uploads/2018/10/vs14.png"></a></p><p>3. DELETE Tutorial/TutorialId — при вызове этого API клиент отправит запрос на удаление из списка TutorialName, которое соответствует переданному TutorialId.</p><p>Запустите Fiddler и выполните следующие действия:</p><ol><li>Переключитесь на вкладку Composer;</li><li>Установите тип запроса равным «DELETE», а в URL вставьте адрес сервиса вместе с id элемента, который хотите удалить. Если мы хотим удалить второй элемент, то адрес будет http://localhost:51056/TutorialService.svc/Tutorial/1.</li></ol><figure><img src="https://media.tproger.ru/user-uploads/34561/2023-12-25/6edb1a54-83f2-49dd-aec2-b63ee4fd7c9f.png" alt="" /></figure><p>Нажмите на кнопку «Execute», чтобы отправить DELETE-запрос на удаление элемента «Queues».</p><p>Если мы опять запросим список всех туториалов, мы увидим, что их стало меньше на один:</p><figure><img src="https://media.tproger.ru/user-uploads/34561/2023-12-25/ca7302e7-4a80-48d2-9ac7-e604b025cac7.png" alt="" /></figure><h3>Подведём итоги</h3><ul><li><a href="https://ru.wikipedia.org/wiki/REST">REST</a> используется для создания легковесных, поддерживаемых и масштабируемых веб-сервисов;</li><li>Всё больше приложений переходят на RESTful архитектуру, что обусловлено большим количеством разнообразных устройств и перемещением многих приложений в облако;</li><li>Основные составляющие REST — ресурсы, которые располагаются на сервере, и методы GET, POST, PUT и DELETE, которые можно использовать для работы с этими ресурсами;</li><li>Для создания RESTful веб-сервисов можно использовать Visual Studio и .NET;</li><li>При проверке работы сервиса с запросами вроде POST, DELETE и PUT нужно использовать сторонний инструмент Fiddler, который позволяет посылать серверу запросы таких типов.</li></ul><p>Чтение по теме:Как защитить веб-приложение: основные советы, инструменты, полезные ссылки</p>]]></content:encoded>
    </item>
    <item>
      <title>Компания Microsoft выпустила июльское обновление .NET Core</title>
      <link>https://tproger.ru/news/microsoft-released-net-core-update</link>
      <comments>https://tproger.ru/news/microsoft-released-net-core-update?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Сергей Штукатуров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/microsoft-released-net-core-update</guid>
      <description><![CDATA[<p>Обновление охватывает .NET Core 1.0.12, 1.1.9, 2.0.9 и 2.1.2: закрыты уязвимости ASP.NET Core, включая атаку по отказу в обработке запроса.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/microsoft-released-net-core-update">Компания Microsoft выпустила июльское обновление .NET Core</a>»</p>]]></description>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[.NET]]></category>
      <category><![CDATA[Microsoft]]></category>
      <category><![CDATA[Asp.NET]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 11 Jul 2018 09:43:59 GMT</pubDate>
      <content:encoded><![CDATA[<p>Компания Microsoft выложила в открытый доступ обновление .NET Core. Оно охватывает .NET Core 1.0.12, .NET Core 1.1.9, .NET Core 2.0.9 и .NET Core 2.1.2.</p><h3>Ключевые изменения .NET Core</h3><p>Microsoft акцентировала внимание на решении проблем с безопасностью. Устранены некоторые уязвимости в ASP.NET Core. Исправлена <a href="https://github.com/aspnet/Announcements/issues/311">ошибка при прерывании неверного запроса</a>, позволявшая злоумышленнику реализовать атаку по отказу в обработке. Помимо этого, компания составила руководство для разработчиков, в продуктах которых присутствует эта уязвимость.</p><p>Устранена ошибка, позволявшая производить <a href="https://github.com/aspnet/Announcements/issues/310">бесконечное количество попыток авторизации</a>. Уязвимость делала продукт неустойчивым к брутфорсу. Теперь приложение будет считать количество попыток аутентификации.</p><p>В ASP.NET Core исправлена <a href="https://github.com/dotnet/announcements/issues/73">ошибка в обработке сертификатов</a>, позволявшая предъявлять по запросу данные с истекшим сроком.</p><p><a href="https://www.microsoft.com/net/download/all">Скачать</a> обновление можно на сайте Microsoft.</p><p>Напомним, NET Core 2.1 <a href="https://tproger.ru/news/release-dot-net-core-2-1/">вышла</a> в конце мая 2018 года, и Microsoft регулярно дорабатывает эту платформу.</p>]]></content:encoded>
    </item>
    <item>
      <title>Курс «Разработка веб-приложений на ASP.NET»</title>
      <link>https://tproger.ru/video/asp-net-development</link>
      <comments>https://tproger.ru/video/asp-net-development?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Дмитрий Баранчук]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/video/asp-net-development</guid>
      <description><![CDATA[<p>Курс посвящён ASP.NET, элементам управления, оформлению страниц, базам данных, AJAX-приложениям и отладке в Visual Studio.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/video/asp-net-development">Курс «Разработка веб-приложений на ASP.NET»</a>»</p>]]></description>
      <category><![CDATA[Asp.NET]]></category>
      <category><![CDATA[Обучающие курсы]]></category>
      <category><![CDATA[Видео]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 07 Sep 2017 01:25:27 GMT</pubDate>
      <content:encoded><![CDATA[<p>Русскоязычный курс от НОУ ИНТУИТ, посвященный вопросам разработки веб-приложений на основе технологии <a href="https://vk.com/away.php?to=http%3A%2F%2FASP.NET&amp;post=-30666517_1495589&amp;cc_key=">ASP.NET</a>.</p><p>В курсе рассматриваются основные сведения и приемы работы с элементами управления, принципы и способы оформления страниц, возможности работы с базами данных. Дается представление о создании скриптов и реализации ajax-приложений, а также основные инструменты отладки веб-приложения в Visual Studio.</p><p>Смотрите еще больше обучающих материалов по ASP.NET.</p>]]></content:encoded>
    </item>
    <item>
      <title>Обзор: создаем погодного бота на основе Microsoft Bot Framework и искусственного интеллекта LUIS</title>
      <link>https://tproger.ru/translations/introduction-microsoft-bot-framework-and-luis</link>
      <comments>https://tproger.ru/translations/introduction-microsoft-bot-framework-and-luis?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Тарас Сереванн]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/translations/introduction-microsoft-bot-framework-and-luis</guid>
      <description><![CDATA[<p>Гайд, как создать погодного бота с помощью инструмента Microsoft Bot Framework и искусственного интеллекта LUIS, который будет понимать человеческий язык и выдавать ответ о погоде </p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/translations/introduction-microsoft-bot-framework-and-luis">Обзор: создаем погодного бота на основе Microsoft Bot Framework и искусственного интеллекта LUIS</a>»</p>]]></description>
      <category><![CDATA[Microsoft]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[Asp.NET]]></category>
      <category><![CDATA[Переводы]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sat, 04 Jun 2016 21:18:18 GMT</pubDate>
      <content:encoded><![CDATA[<p>Очевидно, разработка технологий искусственного интеллекта становится одним из приоритетных направлений в деятельности Microsoft. В ходе пленарного выступления на конференции Build 2016 был анонсирован новый набор инструментов для разработки ботов — Microsoft Bot Framework.</p><p>Для создания ботов даже не потребуется глубокое знание программирования: основные возможности для обучения искусственного интеллекта новым словам и фразам, определенным сценариям и событиям доступны через наглядный интерфейс.</p><figure><img src="https://media.tproger.ru/uploads/2016/06/033016_0449_FromAnalyti2.png" alt="" /></figure><p>В этой статье мы создадим тестового бота с использованием Microsoft Bot Framework, обучим и протестируем его с помощью встроенного эмулятора. Идея бота проста — он должен понимать человеческий язык и отвечать, когда его спросят о погоде в каком-то городе.</p><h3>Архитектура проекта</h3><p>Итак, вот как будет выглядеть схема работы нашего бота:</p><figure><img src="https://media.tproger.ru/uploads/2016/06/chat-bot-flow_2.png" alt="" /></figure><p>Как можно понять, после получения сообщения оно сначала отправляется в «умное» API Microsoft Cognitive Services — <a href="https://www.luis.ai/">Language Understanding Intelligent Service</a>, сокращенно «<a href="https://www.luis.ai/">LUIS</a>». Именно с использованием LUIS мы сможем обучить бота понимать естественный язык и отвечать прогнозом погоды. В ответ на каждое такое сообщение LUIS возвращает всю содержащуюся в нем информацию в JSON.</p><p>Для краткости мы не будем рассказывать о процессе регистрации в Bot Framework и LUIS, так как никаких трудностей с этим возникнуть не должно. Также просим обратить внимание, что на данный момент Microsoft Bot Framework не поддерживает русский язык.</p><h3>Используем LUIS</h3><p>Видео, кратко объясняющее принцип работы LUIS, можно посмотреть <a href="https://www.youtube.com/watch?v=jWeLajon9M8">здесь</a>.</p><p>После регистрации приложения в LUIS перед нами открывается довольно простой интерфейс, в котором мы можем натренировать наш ИИ на определенных фразах. В данном случае обучим его понимать вопросы о погоде:</p><figure><img src="https://media.tproger.ru/uploads/2016/06/luis-samples.png" alt="" /></figure><p>LUIS разбивает приложения на действия, на этом скриншоте их три: погода (weather), состояние (condition) и место (location). Подробнее о действиях (intents) рассказано в официальном видео выше.</p><h3>LUIS в действии</h3><p>Выполнив базовое обучение, попробуем сделать HTTP запрос к LUIS и получить ответ в JSON. Давайте спросим его: «Is it cloudy in Seattle?» («В Сиэтле сейчас облачно?») — и вот что он нам вернет:</p><figure><img src="https://media.tproger.ru/uploads/2016/06/luis-json.png" alt="" /></figure><p>Теперь попытаемся использовать это в реальном боте.</p><h3>Создание бота</h3><p>В качестве платформы будем использовать ASP.NET. Для начала необходимо добавить шаблон Bot Framework в Visual Studio. Подробную инструкцию по этому найдете в <a href="http://docs.botframework.com/connector/getstarted/#getting-started-in-net">официальной документации</a>.</p><p>Теперь создадим новый проект с его использованием:</p><figure><img src="https://media.tproger.ru/uploads/2016/06/bot-vs.png" alt="" /></figure><p>По сути, это простое приложение всего с одним контроллером, который и занимается обработкой сообщений от пользователей. Давайте напишем простой код, который на любое сообщение будет отвечать «Welcome to Streamcode»:</p><figure><img src="https://media.tproger.ru/uploads/2016/06/bot-controller.png" alt="" /></figure><p>По сути, самый простой бот уже готов. Проверить, работает ли он, проще всего через встроенный эмулятор, который, по сути, является просто мессенджером, который подключен к нашему боту.</p><p><a href="http://docs.botframework.com/connector/getstarted/#use-the-bot-framework-emulator-to-test-your-bot-application">Подробная инструкция по установке и настройке эмулятора.</a></p><p>Запустив эмулятор, попробуем пообщаться с новосозданным ботом:</p><figure><img src="https://media.tproger.ru/uploads/2016/06/bot-f-message.png" alt="" /></figure><p>Как и ожидалось, на все сообщения он отвечает одной фразой.</p><h3>Интеграция с LUIS</h3><p>Так как эта статья является вводом в Microsoft Bot Framework, то мы не будем публиковать тут все исходные коды, приведем лишь самые важные. Остальные мы разместили в <a href="https://github.com/mmgrt/streamcode/tree/master/WeatherBot">GitHub-репозитории.</a></p><p>1. Передаем сообщение в LUIS, получаем ответ и на основе наиболее релевантного «действия» (intent) выдаем ответ.</p><figure><img src="https://media.tproger.ru/uploads/2016/06/bot-code.png" alt="" /></figure><p>Прогнозы погоды получаем через API OpenWeatherMap.com.</p><p>2. Заготовленные шаблоны ответов.</p><figure><img src="https://media.tproger.ru/uploads/2016/06/bot-humanlanguage.png" alt="" /></figure><p>Финальный результат:</p><figure><img src="https://media.tproger.ru/uploads/2016/06/bot-weather.png" alt="" /></figure><h3>Материалы для дальнейшего обучения</h3><ol><li><a href="http://docs.botframework.com/">Документация по Bot Framework</a></li><li><a href="https://channel9.msdn.com/Events/Build/2016/B821">Channel9: создаем чат-бота</a></li><li><a href="https://www.luis.uni-hannover.de/archivierung_dokumentation.html?&amp;L=1">Документация по LUIS</a></li><li><a href="https://www.microsoft.com/cognitive-services/">Microsoft Cognitive Services </a></li></ol>]]></content:encoded>
    </item>
    <item>
      <title>ASP.NET 5 умер, да здравствует ASP.NET Core 1.0!</title>
      <link>https://tproger.ru/news/asp-net-5-is-dead</link>
      <comments>https://tproger.ru/news/asp-net-5-is-dead?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Типичный программист]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/asp-net-5-is-dead</guid>
      <description><![CDATA[<p>Скотт Хансельман объясняет, почему переписанный с нуля фреймворк нельзя было называть пятой версией известного уже 15 лет бренда ASP.NET.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/asp-net-5-is-dead">ASP.NET 5 умер, да здравствует ASP.NET Core 1.0!</a>»</p>]]></description>
      <category><![CDATA[.NET]]></category>
      <category><![CDATA[Microsoft]]></category>
      <category><![CDATA[Asp.NET]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 20 Jan 2016 09:57:01 GMT</pubDate>
      <content:encoded><![CDATA[<blockquote>«В программировании есть только две сложных вещи: инвалидация кэша и выбор, как правильно что-нибудь назвать» — Фил Карлтон.</blockquote><p>Как <a href="http://www.hanselman.com/blog/ASPNET5IsDeadIntroducingASPNETCore10AndNETCore10.aspx">сообщает</a> Скотт Хансельман, один из самых известных и уважаемых в мире специалистов по веб-технологиям Microsoft, назвать ASP.NET 5 именно так было неправильно. Понятно, что часто в выборе того, как назвать что-то новое принимает участие больше одного человека, и не всегда выбор так очевиден. К тому же, ASP.NET — это хороший бренд, известный вот уже 15 лет, а ASP.NET 4.6 — выпущенная и поддерживаемая версия продукта, которую можно <a href="https://get.asp.net/">скачать</a> и использовать.</p><p>Но, тем не менее, назвать пятой версией по сути полностью переписанный с нуля ASP.NET фреймворк было плохой идеей т.к. если 5 больше, чем 4.6, то можно подумать, что новая версия также больше, лучше, и полностью заменяет ASP.NET 4.6. Но это не так.</p><p>Итак, встречаем изменения:</p><ul><li>ASP.NET 5 теперь ASP.NET Core 1.0;</li><li>.NET Core 5 становится .NET Core 1.0;</li><li>Entity Framework 7 называем Entity Framework Core 1.0 или EF Core 1.0.</li></ul><p>Почему 1.0? Потому что это нечто новое. Вся концепция  .NET Core стала новой.</p><p>Что же выбрать для своих проектов?</p><p>Чтобы быть до конца честными, скажем, что на текущий момент ASP.NET 4.6 является более взрослой и полноценной платформой. Она хорошо протестирована и доступна для боевого использования уже сейчас. А вот ASP.NET Core 1.0 — это только первый релиз, в котором ещё нет SignalR и Web Pages. В нём не поддерживается VB и F#. Всё это будет, но в будущих версиях.</p>]]></content:encoded>
    </item>
  </channel>
</rss>