ASP.NET Core — Обзор
ASP.NET Core — это новый веб-фреймворк от Microsoft. Он был переработан с нуля, чтобы быть быстрым, гибким, современным и работать на разных платформах. В дальнейшем ASP.NET Core — это фреймворк, который можно использовать для веб-разработки с .NET. Если у вас есть опыт работы с MVC или веб-API за последние несколько лет, вы заметите некоторые знакомые функции. В конце этого учебного пособия у вас будет все необходимое для начала использования ASP.NET Core и написания приложения, которое может создавать, редактировать и просматривать данные из базы данных.
Краткая история ASP.NET
ASP.NET уже много лет используется для разработки веб-приложений. С тех пор инфраструктура претерпела устойчивые эволюционные изменения и, наконец, привела нас к ее последнему потомку ASP.NET Core 1.0.
-
ASP.NET Core 1.0 не является продолжением ASP.NET 4.6.
-
Это совершенно новый фреймворк, параллельный проект, который счастливо живет вместе со всем, что мы знаем.
-
Это фактическое переписывание текущей структуры ASP.NET 4.6, но гораздо меньше и намного более модульно.
-
Некоторые люди думают, что многие вещи остаются прежними, но это не совсем так. ASP.NET Core 1.0 — большое фундаментальное изменение в ландшафте ASP.NET.
ASP.NET Core 1.0 не является продолжением ASP.NET 4.6.
Это совершенно новый фреймворк, параллельный проект, который счастливо живет вместе со всем, что мы знаем.
Это фактическое переписывание текущей структуры ASP.NET 4.6, но гораздо меньше и намного более модульно.
Некоторые люди думают, что многие вещи остаются прежними, но это не совсем так. ASP.NET Core 1.0 — большое фундаментальное изменение в ландшафте ASP.NET.
Что такое ASP.NET Core
ASP.NET Core — это веб-инфраструктура с открытым исходным кодом, оптимизированная для облачных вычислений, для разработки современных веб-приложений, которые можно разрабатывать и запускать на Windows, Linux и Mac. Он включает в себя инфраструктуру MVC, которая теперь объединяет функции MVC и веб-API в единую среду веб-программирования.
-
Приложения ASP.NET Core могут работать на .NET Core или на полной .NET Framework.
-
Он был спроектирован для обеспечения оптимизированной среды разработки для приложений, которые развертываются в облаке или запускаются локально.
-
Он состоит из модульных компонентов с минимальными накладными расходами, поэтому вы сохраняете гибкость при построении ваших решений.
-
Вы можете разрабатывать и запускать кроссплатформенные приложения ASP.NET Core в Windows, Mac и Linux.
Приложения ASP.NET Core могут работать на .NET Core или на полной .NET Framework.
Он был спроектирован для обеспечения оптимизированной среды разработки для приложений, которые развертываются в облаке или запускаются локально.
Он состоит из модульных компонентов с минимальными накладными расходами, поэтому вы сохраняете гибкость при построении ваших решений.
Вы можете разрабатывать и запускать кроссплатформенные приложения ASP.NET Core в Windows, Mac и Linux.
Преимущества ASP.NET Core
ASP.NET Core имеет следующие преимущества:
-
ASP.NET Core имеет ряд архитектурных изменений, которые приводят к гораздо более компактной и модульной структуре.
-
ASP.NET Core больше не основан на System.Web.dll. Он основан на наборе гранулированных и хорошо структурированных пакетов NuGet.
-
Это позволяет оптимизировать ваше приложение, включив в него только те пакеты NuGet, которые вам нужны.
-
Преимущества меньшей площади приложения включают более строгую безопасность, снижение уровня обслуживания, повышение производительности и снижение затрат.
ASP.NET Core имеет ряд архитектурных изменений, которые приводят к гораздо более компактной и модульной структуре.
ASP.NET Core больше не основан на System.Web.dll. Он основан на наборе гранулированных и хорошо структурированных пакетов NuGet.
Это позволяет оптимизировать ваше приложение, включив в него только те пакеты NuGet, которые вам нужны.
Преимущества меньшей площади приложения включают более строгую безопасность, снижение уровня обслуживания, повышение производительности и снижение затрат.
С ASP.NET Core вы можете получить следующие улучшения:
-
Создавайте и запускайте кроссплатформенные приложения ASP.NET в Windows, Mac и Linux.
-
Построен на .NET Core, который поддерживает истинное параллельное управление версиями приложений.
-
Новый инструмент, который упрощает современную разработку wWeb.
-
Единый выровненный веб-стек для веб-интерфейса и веб-API.
-
Готовая к работе среда на основе облака.
-
Встроенная поддержка внедрения зависимостей.
-
Помощники тегов, которые делают разметку Razor более естественной в HTML.
-
Возможность размещения на IIS или самостоятельного размещения в вашем собственном процессе.
Создавайте и запускайте кроссплатформенные приложения ASP.NET в Windows, Mac и Linux.
Построен на .NET Core, который поддерживает истинное параллельное управление версиями приложений.
Новый инструмент, который упрощает современную разработку wWeb.
Единый выровненный веб-стек для веб-интерфейса и веб-API.
Готовая к работе среда на основе облака.
Встроенная поддержка внедрения зависимостей.
Помощники тегов, которые делают разметку Razor более естественной в HTML.
Возможность размещения на IIS или самостоятельного размещения в вашем собственном процессе.
ASP.NET Core — настройка среды
ASP.NET Core — это значительный редизайн ASP.NET. В этом разделе представлены новые концепции в ASP.NET Core и объясняется, как они помогают разрабатывать современные веб-приложения.
Чтобы использовать ASP.NET Core в вашем приложении, в вашей системе должно быть установлено следующее:
- Microsoft Visual Studio 2015
- Microsoft .NET Core 1.0.0 — VS 2015 Tooling Preview 2
Microsoft предоставляет бесплатную версию Visual Studio, которая также содержит SQL Server, и ее можно загрузить с www.visualstudio.com/en-us/downloads/downloadvisual-studio-vs.aspx и Microsoft .NET Core 1.0.0 — VS 2015 Предварительный просмотр Tooling 2 можно загрузить по адресу https://go.microsoft.com/fwlink/?LinkId=817245. ,
Установка Microsoft Visual Studio 2015
Давайте теперь поймем шаги, связанные с установкой
Шаг 1 — После завершения загрузки запустите установщик. Появится следующее диалоговое окно.
Шаг 2 — Нажмите кнопку Установить, как на скриншоте выше. Процесс установки начнется.
Шаг 3 — После успешного завершения процесса установки вы увидите следующее диалоговое окно.
Шаг 4 — Закройте это диалоговое окно и перезагрузите компьютер, если это необходимо.
Шаг 5 — Откройте Visual Studio из меню «Пуск». Откроется следующее диалоговое окно, и это займет некоторое время в первый раз (только для подготовки).
Шаг 6 — Теперь вы увидите главное окно Visual studio.
Шаг 7. После установки Visual Studio закройте Visual Studio и запустите Microsoft .NET Core 1.0.0 — VS 2015 Tooling Preview 2.
Шаг 8 — Установите флажок и нажмите «Установить».
Шаг 9 — После завершения установки вы увидите следующее сообщение.
Шаг 10 — Теперь вы готовы запустить приложение с использованием ASP.NET Core.
ASP.NET Core — новый проект
В этой главе мы обсудим, как создать новый проект в Visual Studio.
После установки инструментария Visual Studio 2015 вы можете приступить к созданию нового базового приложения ASP.NET с помощью пункта меню « Файл» → «Новый проект» .
В диалоговом окне «Новый проект» вы увидите следующие три различных шаблона для веб-проектов:
-
ASP.NET Web Application — Простые шаблоны приложений ASP.NET.
-
Веб-приложение ASP.NET Core (.NET Core). Начнется с кроссплатформенного проекта, совместимого с платформой .NET Core.
-
Базовое веб-приложение ASP.NET (.NET Framework) — запускает новый проект, работающий на стандартном .NET Framework в Windows.
ASP.NET Web Application — Простые шаблоны приложений ASP.NET.
Веб-приложение ASP.NET Core (.NET Core). Начнется с кроссплатформенного проекта, совместимого с платформой .NET Core.
Базовое веб-приложение ASP.NET (.NET Framework) — запускает новый проект, работающий на стандартном .NET Framework в Windows.
На левой панели выберите Шаблоны → Visual C # → Веб и на средней панели выберите шаблон ASP.NET Core Web Application (.NET Core). Давайте назовем это приложение FirstAppDemo, а также укажем Location для вашего проекта ASP.NET Core и затем нажмите OK.
В приведенном выше диалоговом окне вы можете выбрать определенный шаблон для приложения ASP.NET из доступных основных шаблонов ASP.NET.
Шаблоны ASP.NET Core в настоящее время содержат три разных шаблона. Из них шаблон веб-приложения поможет вам выложить множество файлов в вашей файловой системе. Это также позволяет вам использовать ASP.NET MVC сразу.
Здесь мы начнем с пустого шаблона. Это поможет нам построить его с нуля. Давайте выберем Пустой шаблон, выключим Хост в облаке и нажмите ОК.
Visual Studio запустит проект через некоторое время. В окне Solution Explorer вы увидите все файлы, которые есть в этом проекте.
Давайте запустим это приложение, вы можете сделать это, нажав Ctrl + F5 или перейдя в меню Debug. После перехода в меню «Отладка» выберите « Пуск без отладки» .
Это приложение может отображать только Hello World! Это работает на localhost: 57741 . На панели задач окна также видно, что IIS Express работает.
И название сайта FirstAppDemo . Если вы программировали на ASP.NET с предыдущими версиями платформы, как вы будете взаимодействовать с Visual Studio и как Visual Studio использует IIS Express для размещения вашего приложения, все эти аспекты будут знакомы.
ASP.NET Core — макет проекта
В этой главе мы обсудим, как основной проект ASP.NET отображается в файловой системе и как все файлы и каталоги работают вместе.
Давайте откроем проект FirstAppDemo, созданный в предыдущей главе.
В окне обозревателя решений щелкните правой кнопкой мыши узел решения и выберите « Открыть папку в проводнике» .
Теперь вы увидите корневой каталог с двумя файлами: FirstAppDemo.sln и global.json .
FirstAppDemo.sln — это файл решения. Visual Studio по умолчанию использует это расширение годами, и вы можете дважды щелкнуть файл, если хотите открыть приложение в Studio и поработать над ним.
Существует также файл global.json . Давайте откроем этот файл в Visual Studio.
В файле значимы настройки проекта. Этот параметр проекта указывает ASP.NET, где искать исходный код и какие папки содержат ваши проекты.
Существуют две возможные папки « src » для источника и « тестовая » папка. Если ваши проекты и исходный код не находятся в одной из этих двух папок, код не будет доступен для сборки. Вы можете изменить эти настройки, если хотите.
В проводнике Windows есть папка «src» на диске. У вас нет тестовой папки. В папке test вы можете разместить свои проекты модульного тестирования. Давайте дважды щелкнем по папке «src».
Вы можете увидеть проект FirstAppDemo и веб-приложение. Теперь дважды щелкните по папке.
Это файлы исходного кода для приложения, и вы также можете увидеть эту структуру папок в окне обозревателя решений. Это связано с тем, что в текущей версии ASP.NET Core файловая система определяет, что находится в вашем проекте.
Если вы добавите новый файл на диск, файл будет добавлен в проект. Если вы удалите файл, файл будет удален из проекта. Все остается синхронизированным, и это немного отличается от предыдущих версий ASP.NET Core, где файл проекта, файл * .cs proj, содержит манифест всего, что находится в проекте.
ASP.NET Core также компилирует ваше приложение, когда файл изменяется или появляется новый файл.
пример
Давайте посмотрим на простой пример, открыв файл Startup.cs в текстовом редакторе.
Именно эта строка кода отвечает на каждый HTTP-запрос вашего приложения и просто отвечает Hello World!
Давайте изменим строку на приведенном выше снимке экрана, сказав « Привет, мир! Это ASP.NET Core Application », как показано в следующей программе.
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; namespace FirstAppDemo { public class Startup { // This method gets called by the runtime. // Use this method to add services to the container. // For more information on how to configure your application, // visit http://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { } // This method gets called by the runtime. // Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { loggerFactory.AddConsole(); if (env.IsDevelopment()){ app.UseDeveloperExceptionPage(); } app.Run(async (context) => { await context.Response.WriteAsync( "Hello World! This ASP.NET Core Application"); }); } } }
Сохраните этот файл в текстовом редакторе, нажав Ctrl + S, а затем вернитесь в веб-браузер и обновите приложение.
Теперь вы можете видеть, что ваши изменения отражены в браузере.
-
Это связано с тем, что ASP.NET будет отслеживать файловую систему и автоматически перекомпилировать приложение при изменении файла. Вам не нужно явно создавать приложение в Visual Studio.
-
На самом деле, вы можете использовать совершенно другой редактор, что-то вроде кода Visual Studio.
-
Все, что вам нужно сделать с Visual Studio — это запустить веб-сервер, запустив его без отладчика. Вы также можете нажать Ctrl + F5 и редактировать файлы, сохранять файлы и просто обновлять браузер, чтобы увидеть изменения.
-
Это хороший рабочий процесс для создания веб-приложений на скомпилированном языке, таком как C #.
Это связано с тем, что ASP.NET будет отслеживать файловую систему и автоматически перекомпилировать приложение при изменении файла. Вам не нужно явно создавать приложение в Visual Studio.
На самом деле, вы можете использовать совершенно другой редактор, что-то вроде кода Visual Studio.
Все, что вам нужно сделать с Visual Studio — это запустить веб-сервер, запустив его без отладчика. Вы также можете нажать Ctrl + F5 и редактировать файлы, сохранять файлы и просто обновлять браузер, чтобы увидеть изменения.
Это хороший рабочий процесс для создания веб-приложений на скомпилированном языке, таком как C #.
ASP.NET Core — Project.Json
В этой главе мы обсудим файл project.json . Этот файл использует нотацию объектов JavaScript для хранения информации о конфигурации, и именно этот файл является сердцем приложения .NET. Без этого файла у вас не было бы проекта ASP.NET Core. Здесь мы обсудим некоторые из наиболее важных функций этого файла. Давайте дважды щелкнем по файлу project.json .
В настоящее время реализация кода по умолчанию в файле project.json выглядит следующим образом:
{ "dependencies": { "Microsoft.NETCore.App": { "version": "1.0.0", "type": "platform" }, "Microsoft.AspNetCore.Diagnostics": "1.0.0", "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0", "Microsoft.AspNetCore.Server.Kestrel": "1.0.0", "Microsoft.Extensions.Logging.Console": "1.0.0" }, "tools": { "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final" }, "frameworks": { "netcoreapp1.0": { "imports": ["dotnet5.6", "portable-net45+win8"] } }, "buildOptions": { "emitEntryPoint": true, "preserveCompilationContext": true }, "runtimeOptions": { "configProperties": { "System.GC.Server": true } }, "publishOptions": { "include": ["wwwroot", "web.config" ] }, "scripts": { "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ] } }
Как мы видим, у нас есть информация о версии в верхней части этого файла. Это номер версии, который будет использоваться вашим приложением при его создании.
-
Версия 1.0.0, но самая важная часть этого файла — это зависимости.
-
Если ваше приложение выполнит какую-либо полезную работу, то вам понадобятся библиотеки и интегрированные среды для этой работы, такие как хранение и извлечение данных в / из базы данных или рендеринг сложного HTML.
-
В этой версии ASP.NET Core все зависимости управляются через менеджер пакетов NuGet.
-
NuGet работает в пространстве .NET уже несколько лет, но теперь основным способом управления всеми вашими зависимостями является использование библиотек и сред, которые упакованы в пакеты NuGet.
-
Все пакеты NuGet верхнего уровня, в которых нуждается ваше приложение, будут храниться в этом файле project.json.
Версия 1.0.0, но самая важная часть этого файла — это зависимости.
Если ваше приложение выполнит какую-либо полезную работу, то вам понадобятся библиотеки и интегрированные среды для этой работы, такие как хранение и извлечение данных в / из базы данных или рендеринг сложного HTML.
В этой версии ASP.NET Core все зависимости управляются через менеджер пакетов NuGet.
NuGet работает в пространстве .NET уже несколько лет, но теперь основным способом управления всеми вашими зависимостями является использование библиотек и сред, которые упакованы в пакеты NuGet.
Все пакеты NuGet верхнего уровня, в которых нуждается ваше приложение, будут храниться в этом файле project.json.
"Microsoft.AspNetCore.Diagnostics": "1.0.0", "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0", "Microsoft.AspNetCore.Server.Kestrel": "1.0.0", "Microsoft.Extensions.Logging.Console": "1.0.0
Вы можете видеть, что у нас есть некоторые зависимости в этом файле, и точные зависимости, вероятно, изменятся к окончательному выпуску ASP.NET. Если вы хотите добавить новую зависимость, скажем, как ASP.NET MVC, вы легко вводите этот файл project.json, и вы также получите помощь IntelliSense, включая не только имя пакета, но и номера версий, как показано в следующий скриншот.
Вы также можете использовать пользовательский интерфейс, щелкнув правой кнопкой мыши References в обозревателе решений, а затем выберите Управление пакетами NuGet. Теперь вы можете увидеть установленные в данный момент пакеты.
Эти пакеты те же, что и в вашем файле project.json, и вы также можете перейти в Браузер и добавить другие пакеты, включая предварительно выпущенные пакеты, скажем, среду MVC, установленную в этом проекте.
Если вы установите этот пакет прямо сейчас с помощью кнопки «Установить», этот пакет будет сохранен в project.json. Раздел фреймворков — это еще одна важная часть project.json, в этом разделе рассказывается ASP.NET о том, какую из фреймворков .NET можно использовать в вашем приложении.
"рамки": { "netcoreapp1.0": { "импорт": [ "Dotnet5.6", "Портативный-net45 + Win8" ] } },
В этом случае вы увидите, что « netcoreapp1.0 » — это фреймворк, используемый в проекте, вы также можете включить полный .NET Framework, который устанавливается при установке Visual Studio.
-
Это тот же .NET Framework, который включен во многие версии операционной системы Windows.
-
Это платформа .NET Framework, которая существует уже 15 лет и включает в себя интегрированные среды, которые делают все, от веб-программирования до настольного программирования.
-
Это огромный фреймворк, который работает только на Windows.
-
«Netcoreapp1.0» — это платформа .NET Core. Это кроссплатформенный фреймворк, который может работать на разных платформах, не только Windows, но также OS X и Linux.
-
Этот каркас имеет меньше возможностей, чем полноценный каркас .NET, но в нем есть все функции, которые нам нужны для веб-разработки ASP.NET Core.
Это тот же .NET Framework, который включен во многие версии операционной системы Windows.
Это платформа .NET Framework, которая существует уже 15 лет и включает в себя интегрированные среды, которые делают все, от веб-программирования до настольного программирования.
Это огромный фреймворк, который работает только на Windows.
«Netcoreapp1.0» — это платформа .NET Core. Это кроссплатформенный фреймворк, который может работать на разных платформах, не только Windows, но также OS X и Linux.
Этот каркас имеет меньше возможностей, чем полноценный каркас .NET, но в нем есть все функции, которые нам нужны для веб-разработки ASP.NET Core.
ASP.NET Core — Конфигурация
В этой главе мы обсудим конфигурацию, связанную с проектом ASP.NET Core. В обозревателе решений вы увидите файл Startup.cs. Если вы работали с предыдущими версиями ASP.NET Core, вы, вероятно, ожидаете увидеть файл global.asax, в котором можно было писать коды для выполнения во время запуска веб-приложения.
-
Вы также ожидаете увидеть файл web.config, содержащий все параметры конфигурации, которые необходимо выполнить вашему приложению.
-
В ASP.NET Core все эти файлы пропали, и вместо конфигурации и кода загрузки загружаются из Startup.cs.
-
Внутри файла есть класс Startup, и в этом классе вы можете настроить свое приложение и даже настроить источники конфигурации.
Вы также ожидаете увидеть файл web.config, содержащий все параметры конфигурации, которые необходимо выполнить вашему приложению.
В ASP.NET Core все эти файлы пропали, и вместо конфигурации и кода загрузки загружаются из Startup.cs.
Внутри файла есть класс Startup, и в этом классе вы можете настроить свое приложение и даже настроить источники конфигурации.
Вот реализация по умолчанию в файле Startup.cs .
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; namespace FirstAppDemo { public class Startup { // This method gets called by the runtime. // Use this method to add services to the container. // For more information on how to configure your application, // visit http://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { } // This method gets called by the runtime. Use this method to configure // the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { loggerFactory.AddConsole(); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.Run(async (context) => { await context.Response.WriteAsync("Hello World!"); }); } } }
В классе Startup есть два метода, в которых будет проходить большая часть нашей работы. Метод Configure класса — это место, где вы строите свой конвейер обработки HTTP.
-
Это определяет, как ваше приложение отвечает на запросы. В настоящее время это приложение может сказать только Hello World! и если мы хотим, чтобы приложение работало иначе, нам нужно будет изменить конвейер, добавив дополнительный код в этот метод Configure.
-
Например, если мы хотим обслуживать статические файлы, такие как файл index.html, нам потребуется добавить некоторый код в метод Configure.
-
Вы также можете иметь страницу с ошибкой или направлять запросы к контроллеру ASP.NET MVC; оба эти сценария также потребуют выполнения некоторых действий в этом методе Configure.
-
В классе Startup вы также увидите метод ConfigureServices () . Это поможет вам настроить компоненты для вашего приложения.
Это определяет, как ваше приложение отвечает на запросы. В настоящее время это приложение может сказать только Hello World! и если мы хотим, чтобы приложение работало иначе, нам нужно будет изменить конвейер, добавив дополнительный код в этот метод Configure.
Например, если мы хотим обслуживать статические файлы, такие как файл index.html, нам потребуется добавить некоторый код в метод Configure.
Вы также можете иметь страницу с ошибкой или направлять запросы к контроллеру ASP.NET MVC; оба эти сценария также потребуют выполнения некоторых действий в этом методе Configure.
В классе Startup вы также увидите метод ConfigureServices () . Это поможет вам настроить компоненты для вашего приложения.
Прямо сейчас у нас есть жестко запрограммированная строка для каждого ответа — Hello World ! строка. Вместо жесткого кодирования строки, мы хотим загрузить эту строку из некоторого компонента, который знает текст, который мы хотим отобразить.
-
Этот другой компонент может загружать этот текст из базы данных, веб-службы или файла JSON, не имеет значения, где именно он находится.
-
Мы просто настроим сценарий, чтобы у нас не было этой жестко запрограммированной строки.
Этот другой компонент может загружать этот текст из базы данных, веб-службы или файла JSON, не имеет значения, где именно он находится.
Мы просто настроим сценарий, чтобы у нас не было этой жестко запрограммированной строки.
В обозревателе решений щелкните правой кнопкой мыши узел своего проекта и выберите « Добавить» → «Новый элемент» .
На левой панели выберите Установлено → Код, а затем на средней панели выберите файл JSON. Вызовите этот файл AppSettings.json и нажмите кнопку « Добавить» , как показано на скриншоте выше.
Мы также можем заставить нашу программу читать текст из файла вместо Hello World! Строка в Startup.cs. Давайте добавим следующий код в файл AppSettings.json .
{ "message": "Hello, World! this message is from configuration file..." }
Теперь нам нужно получить доступ к этому сообщению из файла Startup.cs. Вот реализация файла Startup.cs, который будет читать вышеупомянутое сообщение из файла JSON.
using Microsoft.AspNet.Builder; using Microsoft.AspNet.Hosting; using Microsoft.AspNet.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Configuration; namespace FirstAppDemo { public class Startup { public Startup() { var builder = new ConfigurationBuilder() .AddJsonFile("AppSettings.json"); Configuration = builder.Build(); } public IConfiguration Configuration { get; set; } // This method gets called by the runtime. // Use this method to add services to the container. // For more information on how to configure your application, // visit http://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { } // This method gets called by the runtime. // Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app) { app.UseIISPlatformHandler(); app.Run(async (context) => { var msg = Configuration["message"]; await context.Response.WriteAsync(msg); }); } // Entry point for the application. public static void Main(string[] args) =7gt; WebApplication.Run<Startup>(args); } }
Давайте теперь запустим приложение. Как только вы запустите приложение, оно выдаст следующий вывод.
ASP.NET Core — промежуточное ПО
В этой главе мы поймем, как настроить промежуточное программное обеспечение. Промежуточное программное обеспечение в ASP.NET Core контролирует, как наше приложение реагирует на HTTP-запросы. Он также может контролировать то, как выглядит наше приложение при возникновении ошибки, и это ключевой момент в том, как мы аутентифицируем и уполномочиваем пользователя выполнять определенные действия.
-
Промежуточное программное обеспечение — это программные компоненты, которые собираются в конвейер приложения для обработки запросов и ответов.
-
Каждый компонент выбирает, передавать ли запрос следующему компоненту в конвейере, и может выполнять определенные действия до и после вызова следующего компонента в конвейере.
-
Делегаты запросов используются для построения конвейера запросов. Делегаты запроса обрабатывают каждый HTTP-запрос.
-
Каждая часть промежуточного программного обеспечения в ASP.NET Core является объектом, и каждая часть играет очень специфическую, целенаправленную и ограниченную роль.
-
В конечном итоге нам нужно много промежуточного программного обеспечения, чтобы приложение работало надлежащим образом.
Промежуточное программное обеспечение — это программные компоненты, которые собираются в конвейер приложения для обработки запросов и ответов.
Каждый компонент выбирает, передавать ли запрос следующему компоненту в конвейере, и может выполнять определенные действия до и после вызова следующего компонента в конвейере.
Делегаты запросов используются для построения конвейера запросов. Делегаты запроса обрабатывают каждый HTTP-запрос.
Каждая часть промежуточного программного обеспечения в ASP.NET Core является объектом, и каждая часть играет очень специфическую, целенаправленную и ограниченную роль.
В конечном итоге нам нужно много промежуточного программного обеспечения, чтобы приложение работало надлежащим образом.
Теперь давайте предположим, что мы хотим регистрировать информацию о каждом запросе в нашем приложении.
-
В этом случае первым компонентом промежуточного программного обеспечения, которое мы могли бы установить в приложение, является компонент журналирования.
-
Этот регистратор может видеть все о входящем запросе, но есть вероятность, что регистратор просто собирается записать некоторую информацию и затем передать этот запрос следующему фрагменту промежуточного программного обеспечения.
В этом случае первым компонентом промежуточного программного обеспечения, которое мы могли бы установить в приложение, является компонент журналирования.
Этот регистратор может видеть все о входящем запросе, но есть вероятность, что регистратор просто собирается записать некоторую информацию и затем передать этот запрос следующему фрагменту промежуточного программного обеспечения.
-
Промежуточное программное обеспечение — это набор компонентов, присутствующих в этом конвейере обработки.
-
Следующее промежуточное ПО, которое мы установили в приложение, — это авторизатор.
-
Авторизатор может искать определенные cookie или токены доступа в заголовках HTTP.
-
Если авторизатор находит токен, он разрешает выполнение запроса. Если нет, возможно, авторизатор сам ответит на запрос кодом ошибки HTTP или кодом перенаправления, чтобы отправить пользователя на страницу входа.
-
Но, в противном случае, авторизатор передаст запрос следующему компоненту промежуточного программного обеспечения, который является маршрутизатором.
-
Маршрутизатор просматривает URL-адрес и определяет ваш следующий шаг.
-
Маршрутизатор просматривает приложение, чтобы что-то ответить, и если маршрутизатор не находит ничего, чтобы ответить, сам маршрутизатор может вернуть ошибку 404 Not Found .
Промежуточное программное обеспечение — это набор компонентов, присутствующих в этом конвейере обработки.
Следующее промежуточное ПО, которое мы установили в приложение, — это авторизатор.
Авторизатор может искать определенные cookie или токены доступа в заголовках HTTP.
Если авторизатор находит токен, он разрешает выполнение запроса. Если нет, возможно, авторизатор сам ответит на запрос кодом ошибки HTTP или кодом перенаправления, чтобы отправить пользователя на страницу входа.
Но, в противном случае, авторизатор передаст запрос следующему компоненту промежуточного программного обеспечения, который является маршрутизатором.
Маршрутизатор просматривает URL-адрес и определяет ваш следующий шаг.
Маршрутизатор просматривает приложение, чтобы что-то ответить, и если маршрутизатор не находит ничего, чтобы ответить, сам маршрутизатор может вернуть ошибку 404 Not Found .
пример
Давайте теперь возьмем простой пример, чтобы больше узнать о промежуточном программном обеспечении. Мы установили промежуточное программное обеспечение в ASP.NET, используя метод Configure нашего класса Startup .
using Microsoft.AspNet.Builder; using Microsoft.AspNet.Hosting; using Microsoft.AspNet.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Configuration; namespace FirstAppDemo { public class Startup { public Startup() { var builder = new ConfigurationBuilder() .AddJsonFile("AppSettings.json"); Configuration = builder.Build(); } public IConfiguration Configuration { get; set; } // This method gets called by the runtime. // Use this method to add services to the container. // For more information on how to configure your application, // visit http://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { } // This method gets called by the runtime. // Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app) { app.UseIISPlatformHandler(); app.Run(async (context) => { var msg = Configuration["message"]; await context.Response.WriteAsync(msg); }); } // Entry point for the application. public static void Main(string[] args) => WebApplication.Run<Startup>(args); } }
Внутри метода Configure () мы будем вызывать методы расширения в интерфейсе IApplicationBuilder для добавления промежуточного программного обеспечения.
По умолчанию в новом пустом проекте есть два промежуточных ПО —
- IISPlatformHandler
- Промежуточное программное обеспечение зарегистрировано в app.Run
IISPlatformHandler
IISPlatformHandler позволяет нам работать с аутентификацией Windows. Он просматривает каждый входящий запрос и проверяет, есть ли какая-либо информация об идентификации Windows, связанная с этим запросом, а затем вызывает следующий компонент промежуточного программного обеспечения.
Промежуточное программное обеспечение зарегистрировано в app.Run
Следующий кусок промежуточного программного обеспечения в этом случае — это промежуточное ПО, зарегистрированное в app.Run . Метод Run позволяет нам передавать другой метод, который мы можем использовать для обработки каждого отдельного ответа. Run — это не то, что вы увидите очень часто, это то, что мы называем конечной частью промежуточного программного обеспечения.
Промежуточное программное обеспечение, которое вы регистрируете в Run, никогда не будет иметь возможности вызвать другой компонент промежуточного программного обеспечения, все, что он делает, — это получает запрос, а затем он должен произвести какой-то ответ.
Вы также получаете доступ к объекту Response, и одна из вещей, которые вы можете сделать с объектом Response, — это написать строку.
Если вы хотите зарегистрировать другую часть промежуточного программного обеспечения после app.Run, эта часть промежуточного программного обеспечения никогда не будет вызываться, потому что, опять же, Run является конечной частью промежуточного программного обеспечения. Это никогда не вызовет следующий кусок промежуточного программного обеспечения.
Как добавить еще одно промежуточное ПО
Давайте продолжим со следующих шагов, чтобы добавить другое промежуточное ПО —
Шаг 1. Чтобы добавить другое промежуточное ПО, щелкните правой кнопкой мыши проект и выберите «Управление пакетами NuGet».
Шаг 2. Поиск Microsoft.aspnet.diagnostics, который на самом деле является промежуточным программным обеспечением ASP.NET Core для обработки исключений, страниц отображения исключений и диагностической информации. Этот конкретный пакет содержит много разных промежуточных программ, которые мы можем использовать.
Шаг 3 — Установите этот пакет, если он не установлен в вашем проекте.
Шаг 4. Теперь перейдем к методу Configure () и вызовем промежуточное программное обеспечение app.UseWelcomePage .
// This method gets called by the runtime. // Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app) { app.UseIISPlatformHandler(); app.UseWelcomePage(); app.Run(async (context) => { var msg = Configuration["message"]; await context.Response.WriteAsync(msg); }); }
Шаг 5 — Запустите ваше приложение, и вы увидите следующий экран приветствия.
Этот экран приветствия может быть не таким полезным.
Шаг 6 — Давайте попробуем что-нибудь еще, что может быть немного более полезным. Вместо использования страницы приветствия мы будем использовать RuntimeInfoPage .
// This method gets called by the runtime. // Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app) { app.UseIISPlatformHandler(); app.UseRuntimeInfoPage(); app.Run(async (context) => { var msg = Configuration["message"]; await context.Response.WriteAsync(msg); }); }
Шаг 7 — Сохраните страницу Startup.cs и обновите браузер, и вы увидите следующую страницу.
Этот RuntimeInfoPage является промежуточным программным обеспечением, которое будет отвечать только на запросы, поступающие для определенного URL-адреса. Если входящий запрос не совпадает с этим URL-адресом, эта промежуточная программа просто пропускает запрос к следующей промежуточной программе. Запрос пройдет через промежуточное программное обеспечение IISPlatformHandler, а затем перейдет к промежуточному программному обеспечению UseRuntimeInfoPage. Он не собирается создавать ответ, поэтому он перейдет к нашему app.Run и отобразит строку.
Шаг 8 — Давайте добавим «/ runtimeinfo » в конце вашего URL. Теперь вы увидите страницу, созданную промежуточным программным обеспечением этой страницы информации о времени выполнения.
Теперь вы увидите ответ, содержащий некоторую информацию о вашей среде выполнения, такую как операционная система, версия времени выполнения, архитектура, тип и все используемые вами пакеты и т. Д.
ASP.NET Core — исключения
В этой главе мы обсудим исключения и обработку ошибок . Когда в приложении ASP.NET Core возникают ошибки, вы можете обрабатывать их различными способами. Давайте посмотрим на дополнительную часть промежуточного программного обеспечения, которая доступна через пакет диагностики. Эта часть промежуточного программного обеспечения поможет нам обрабатывать ошибки.
Чтобы смоделировать ошибку, давайте перейдем к app.Run и посмотрим, как ведет себя приложение, если мы просто генерируем исключение каждый раз, когда сталкиваемся с этим промежуточным программным обеспечением.
using Microsoft.AspNet.Builder; using Microsoft.AspNet.Hosting; using Microsoft.AspNet.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Configuration; namespace FirstAppDemo { public class Startup { public Startup() { var builder = new ConfigurationBuilder() .AddJsonFile("AppSettings.json"); Configuration = builder.Build(); } public IConfiguration Configuration { get; set; } // This method gets called by the runtime. // Use this method to add services to the container. // For more information on how to configure your application, // visit http://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { } // This method gets called by the runtime. // Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app) { app.UseIISPlatformHandler(); app.UseRuntimeInfoPage(); app.Run(async (context) => { throw new System.Exception("Throw Exception"); var msg = Configuration["message"]; await context.Response.WriteAsync(msg); }); } // Entry point for the application. public static void Main(string[] args) => WebApplication.Run<Startup>(args); } }
Это просто сгенерирует исключение с очень общим сообщением. Сохраните страницу Startup.cs и запустите ваше приложение.
Вы увидите, что нам не удалось загрузить этот ресурс. Произошла ошибка HTTP 500, внутренняя ошибка сервера, и это не очень полезно. Было бы неплохо получить информацию об исключении.
Давайте добавим еще один компонент промежуточного программного обеспечения, который представляет собой UseDeveloperExceptionPage .
// This method gets called by the runtime. // Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app) { app.UseIISPlatformHandler(); app.UseDeveloperExceptionPage(); app.UseRuntimeInfoPage(); app.Run(async (context) => { throw new System.Exception("Throw Exception"); var msg = Configuration["message"]; await context.Response.WriteAsync(msg); }); }
-
Эта часть промежуточного программного обеспечения немного отличается от других частей промежуточного программного обеспечения, остальные части промежуточного программного обеспечения обычно рассматривают входящий запрос и принимают определенное решение по этому запросу.
-
UseDeveloperExceptionPage не столько заботится о входящих запросах, сколько делает то, что происходит позже в конвейере.
-
Он просто вызовет следующую часть промежуточного программного обеспечения, но затем он будет ждать, чтобы увидеть, генерирует ли что-нибудь позднее в конвейере исключение, и если есть исключение, этот промежуточный компонент выдаст вам страницу с ошибкой с некоторыми дополнительная информация об этом исключении.
Эта часть промежуточного программного обеспечения немного отличается от других частей промежуточного программного обеспечения, остальные части промежуточного программного обеспечения обычно рассматривают входящий запрос и принимают определенное решение по этому запросу.
UseDeveloperExceptionPage не столько заботится о входящих запросах, сколько делает то, что происходит позже в конвейере.
Он просто вызовет следующую часть промежуточного программного обеспечения, но затем он будет ждать, чтобы увидеть, генерирует ли что-нибудь позднее в конвейере исключение, и если есть исключение, этот промежуточный компонент выдаст вам страницу с ошибкой с некоторыми дополнительная информация об этом исключении.
Теперь давайте снова запустим приложение. Он выдаст вывод, как показано на следующем снимке экрана.
Теперь вы увидите некоторую информацию, которую вы ожидаете, если в процессе разработки произошла ошибка. Вы также получите трассировку стека и увидите, что в строке 37 файла Startup.cs возникло необработанное исключение.
Вы также можете увидеть необработанные подробности исключений, и вся эта информация может быть очень полезна для разработчика. Фактически, мы, вероятно, хотим показывать эту информацию только тогда, когда разработчик запускает приложение.
ASP.NET Core — статические файлы
В этой главе мы научимся работать с файлами. Важной функцией, которая нужна почти каждому веб-приложению, является возможность обслуживать файлы (статические файлы) из файловой системы.
-
Статические файлы, такие как файлы JavaScript, изображения, файлы CSS, которые есть в нашей файловой системе, являются активами, которые приложение ASP.NET Core может обслуживать напрямую клиентам.
-
Статические файлы обычно находятся в корневой веб-папке (wwwroot).
-
По умолчанию это единственное место, где мы можем обслуживать файлы непосредственно из файловой системы.
Статические файлы, такие как файлы JavaScript, изображения, файлы CSS, которые есть в нашей файловой системе, являются активами, которые приложение ASP.NET Core может обслуживать напрямую клиентам.
Статические файлы обычно находятся в корневой веб-папке (wwwroot).
По умолчанию это единственное место, где мы можем обслуживать файлы непосредственно из файловой системы.
пример
Давайте теперь возьмем простой пример, в котором мы поймем, как мы можем обслуживать эти файлы в нашем приложении.
Здесь мы хотим добавить простой HTML-файл в наше приложение FirstAppDemo, и этот HTML-файл должен перейти в корневую веб-папку (wwwroot). Щелкните правой кнопкой мыши папку wwwroot в обозревателе решений и выберите « Добавить» → «Новый элемент» .
В средней панели выберите страницу HTML, назовите ее index.html и нажмите кнопку « Добавить» .
Вы увидите простой файл index.html . Давайте добавим простой текст и заголовок, как показано ниже.
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Welcome to ASP.NET Core</title> </head> <body> Hello, Wolrd! this message is from our first static HTML file. </body> </html>
Когда вы запустите свое приложение и перейдете к index.html в браузере, вы увидите, что промежуточное ПО app.Run выдает исключение, поскольку в нашем приложении в настоящий момент ничего нет.
Не существует промежуточного программного обеспечения, которое будет искать любой файл в файловой системе для обслуживания. Чтобы устранить эту проблему, перейдите в диспетчер пакетов NuGet , щелкнув правой кнопкой мыши свой проект в обозревателе решений и выбрав Управление пакетами NuGet.
Найдите файл Microsoft.AspNet.StaticFiles, который найдет статическое промежуточное ПО для файлов. Давайте установим этот пакет nuget, и теперь у нас должны быть дополнительные методы, которые мы можем использовать для регистрации промежуточного программного обеспечения внутри метода Configure.
Давайте добавим середину UseStaticFiles в метод Configure, как показано в следующей программе.
using Microsoft.AspNet.Builder; using Microsoft.AspNet.Hosting; using Microsoft.AspNet.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Configuration; namespace FirstAppDemo { public class Startup { public Startup() { var builder = new ConfigurationBuilder() .AddJsonFile("AppSettings.json"); Configuration = builder.Build(); } public IConfiguration Configuration { get; set; } // This method gets called by the runtime. // Use this method to add services to the container. // For more information on how to configure your application, // visit http://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { } // This method gets called by the runtime. // Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app) { app.UseIISPlatformHandler(); app.UseDeveloperExceptionPage(); app.UseRuntimeInfoPage(); app.UseStaticFiles(); app.Run(async (context) => { throw new System.Exception("Throw Exception"); var msg = Configuration["message"]; await context.Response.WriteAsync(msg); }); } // Entry point for the application. public static void Main(string[] args) => WebApplication.Run<Startup>(args); } }
Если вы не переопределите параметры и не передадите некоторые другие параметры конфигурации, статические файлы будут делать для данного запроса только просмотр пути запроса . Этот путь запроса затем сравнивается с файловой системой и тем, что находится в файловой системе.
-
Если статический файл видит файл, который он может использовать, он будет обслуживать этот файл и не будет вызывать следующую часть промежуточного программного обеспечения.
-
Если он не найдет подходящий файл, он просто перейдет к следующему фрагменту промежуточного программного обеспечения.
Если статический файл видит файл, который он может использовать, он будет обслуживать этот файл и не будет вызывать следующую часть промежуточного программного обеспечения.
Если он не найдет подходящий файл, он просто перейдет к следующему фрагменту промежуточного программного обеспечения.
Давайте сохраним файл Startup.cs и обновим ваш браузер.
Теперь вы можете увидеть файл index.html. Все, что вы поместите в любое место внутри wwwroot — любой файл JavaScript, CSS или HTML, вы сможете их обработать.
-
Теперь, если вы хотите, чтобы index.html был вашим файлом по умолчанию, эта функция всегда была в IIS.
-
Вы всегда можете дать IIS список файлов по умолчанию для поиска. Если кто-то попадет в корень каталога или, в данном случае, в корень веб-сайта и если IIS найдет что-то с именем index.html, он просто автоматически предоставит этот файл.
-
Давайте начнем с внесения нескольких изменений. Сначала нам нужно удалить принудительную ошибку, а затем добавить еще один компонент промежуточного программного обеспечения, который называется UseDefaultFiles. Ниже приведена реализация метода Configure.
Теперь, если вы хотите, чтобы index.html был вашим файлом по умолчанию, эта функция всегда была в IIS.
Вы всегда можете дать IIS список файлов по умолчанию для поиска. Если кто-то попадет в корень каталога или, в данном случае, в корень веб-сайта и если IIS найдет что-то с именем index.html, он просто автоматически предоставит этот файл.
Давайте начнем с внесения нескольких изменений. Сначала нам нужно удалить принудительную ошибку, а затем добавить еще один компонент промежуточного программного обеспечения, который называется UseDefaultFiles. Ниже приведена реализация метода Configure.
// This method gets called by the runtime. // Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app) { app.UseIISPlatformHandler(); app.UseDeveloperExceptionPage(); app.UseRuntimeInfoPage(); app.UseDefaultFiles(); app.UseStaticFiles(); app.Run(async (context) => { var msg = Configuration["message"]; await context.Response.WriteAsync(msg); }); }
-
Эта часть промежуточного программного обеспечения будет смотреть на входящий запрос и определять, является ли он корневым каталогом и есть ли какие-либо подходящие файлы по умолчанию.
-
Вы можете переопределить параметры для этого промежуточного программного обеспечения, чтобы указать, какие файлы по умолчанию искать, но Index.html по умолчанию является одним из файлов по умолчанию.
Эта часть промежуточного программного обеспечения будет смотреть на входящий запрос и определять, является ли он корневым каталогом и есть ли какие-либо подходящие файлы по умолчанию.
Вы можете переопределить параметры для этого промежуточного программного обеспечения, чтобы указать, какие файлы по умолчанию искать, но Index.html по умолчанию является одним из файлов по умолчанию.
Давайте сохраним файл Startup.cs и перейдем в корневой каталог веб-приложения в вашем браузере.
Теперь вы можете видеть, что index.html — ваш файл по умолчанию. Порядок, в котором вы устанавливаете промежуточное ПО, важен, потому что если бы вы использовали UseDefaultFiles после UseStaticFiles, вы бы не получили тот же результат.
Если вы собираетесь использовать UseDefaultFiles и UseStaticFiles, вам также может понадобиться другая часть промежуточного программного обеспечения, которая находится внутри пакета Microsoft.aspnet.staticfiles, пакета NuGet, и это промежуточное программное обеспечение FileServer . По сути это включает в себя файлы по умолчанию и статические файлы в правильном порядке.
// This method gets called by the runtime. // Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app) { app.UseIISPlatformHandler(); app.UseDeveloperExceptionPage(); app.UseRuntimeInfoPage(); app. UseFileServer(); app.Run(async (context) => { var msg = Configuration["message"]; await context.Response.WriteAsync(msg); }); }
Давайте снова сохраним файл Startup.cs . После обновления браузера вы увидите тот же результат, что и на следующем снимке экрана.
ASP.NET Core — Настройка MVC
В этой главе мы настроим инфраструктуру MVC в нашем приложении FirstAppDemo. Мы продолжим построение веб-приложения поверх ASP.NET Core и, более конкретно, платформы ASP.NET Core MVC. Технически мы можем построить целое приложение, используя только промежуточное программное обеспечение, но ASP.NET Core MVC предоставляет нам функции, которые мы можем использовать для простого создания HTML-страниц и API на основе HTTP.
Чтобы настроить MVC Framework в нашем пустом проекте, выполните следующие действия:
-
Установите пакет Microsoft.AspNet.Mvc , который дает нам доступ к сборкам и классам, предоставляемым платформой.
-
После установки пакета нам нужно зарегистрировать все службы, которые требуются ASP.NET MVC во время выполнения. Мы сделаем это внутри метода ConfigureServices .
-
Наконец, нам нужно добавить промежуточное программное обеспечение для ASP.NET MVC для получения запросов. По сути, эта часть промежуточного программного обеспечения принимает HTTP-запрос и пытается направить этот запрос в класс C #, который мы напишем.
Установите пакет Microsoft.AspNet.Mvc , который дает нам доступ к сборкам и классам, предоставляемым платформой.
После установки пакета нам нужно зарегистрировать все службы, которые требуются ASP.NET MVC во время выполнения. Мы сделаем это внутри метода ConfigureServices .
Наконец, нам нужно добавить промежуточное программное обеспечение для ASP.NET MVC для получения запросов. По сути, эта часть промежуточного программного обеспечения принимает HTTP-запрос и пытается направить этот запрос в класс C #, который мы напишем.
Шаг 1 — Давайте перейдем к диспетчеру пакетов NuGet, щелкнув правой кнопкой мыши на Управление пакетами NuGet. Установите пакет Microsoft.AspNet.Mvc, который дает нам доступ к сборкам и классам, предоставляемым платформой.
Шаг 2. После установки пакета Microsoft.AspNet.Mvc нам необходимо зарегистрировать все службы, которые требуются ASP.NET Core MVC во время выполнения. Мы сделаем это с помощью метода ConfigureServices. Мы также добавим простой контроллер и увидим некоторый вывод этого контроллера.
Давайте добавим новую папку в этот проект и назовем ее Controllers . В этой папке мы можем разместить несколько контроллеров, как показано ниже в обозревателе решений.
Теперь щелкните правой кнопкой мыши папку «Контроллеры» и выберите пункт меню « Добавить → Класс» .
Шаг 3 — Здесь мы хотим добавить простой класс C # и вызвать этот класс HomeController, а затем нажать кнопку «Добавить», как показано на скриншоте выше.
Это будет наша страница по умолчанию.
Шаг 4 — Давайте определим один открытый метод, который возвращает строку, и вызовем этот метод Index, как показано в следующей программе.
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace FirstAppdemo.Controllers { public class HomeController { public string Index() { return "Hello, World! this message is from Home Controller..."; } } }
Шаг 5 — Когда вы идете в корень сайта, вы хотите увидеть ответ контроллера. На данный момент мы будем обслуживать наш файл index.html.
Давайте перейдем в корень сайта и удалим index.html. Мы хотим, чтобы контроллер отвечал вместо файла index.html .
Шаг 6 — Теперь перейдите к методу Configure в классе Startup и добавьте часть промежуточного программного обеспечения UseMvcWithDefaultRoute .
Шаг 7 — Теперь обновите приложение в корне сайта.
Вы столкнетесь с ошибкой 500. Ошибка говорит о том, что каркасу не удалось найти необходимые службы ASP.NET Core MVC.
Сам ASP.NET Core Framework состоит из различных небольших компонентов, которые имеют очень сфокусированные обязанности.
Например, есть компонент, который должен найти и создать экземпляр контроллера.
Этот компонент должен быть в коллекции сервисов, чтобы ASP.NET Core MVC функционировал правильно.
Шаг 8. Помимо добавления пакета NuGet и промежуточного программного обеспечения, нам также необходимо добавить службу AddMvc в ConfigureServices. Вот полная реализация класса Startup.
using Microsoft.AspNet.Builder; using Microsoft.AspNet.Hosting; using Microsoft.AspNet.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Configuration; namespace FirstAppDemo { public class Startup { public Startup() { var builder = new ConfigurationBuilder() .AddJsonFile("AppSettings.json"); Configuration = builder.Build(); } public IConfiguration Configuration { get; set; } // This method gets called by the runtime. // Use this method to add services to the container. // For more information on how to configure your application, // visit http://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { services.AddMvc(); } // This method gets called by the runtime. // Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app) { app.UseIISPlatformHandler(); app.UseDeveloperExceptionPage(); app.UseRuntimeInfoPage(); app.UseFileServer(); app.UseMvcWithDefaultRoute(); app.Run(async (context) => { var msg = Configuration["message"]; await context.Response.WriteAsync(msg); }); } // Entry point for the application. public static void Main(string[] args) => WebApplication.Run<Startup>(args); } }
Шаг 9 — Сохраните файл Startup.cs и перейдите в браузер и обновите его. Теперь вы получите ответ от нашего домашнего контроллера .
ASP.NET Core — шаблон проектирования MVC
Шаблон проектирования MVC (Model-View-Controller) — это шаблон проектирования, который на самом деле существовал в течение нескольких десятилетий, и он использовался во многих различных технологиях, от Smalltalk до C ++ и Java, а теперь в C # и .NET как дизайн. шаблон для использования при создании пользовательского интерфейса.
-
Шаблон проектирования MVC является популярным шаблоном проектирования для уровня пользовательского интерфейса программного приложения.
-
В более крупных приложениях вы обычно комбинируете уровень пользовательского интерфейса контроллера модели с другими шаблонами проектирования в приложении, такими как шаблоны доступа к данным и шаблоны обмена сообщениями.
-
Все это пойдет вместе для создания полного стека приложений.
Шаблон проектирования MVC является популярным шаблоном проектирования для уровня пользовательского интерфейса программного приложения.
В более крупных приложениях вы обычно комбинируете уровень пользовательского интерфейса контроллера модели с другими шаблонами проектирования в приложении, такими как шаблоны доступа к данным и шаблоны обмена сообщениями.
Все это пойдет вместе для создания полного стека приложений.
MVC разделяет пользовательский интерфейс приложения на следующие три части:
-
Модель — набор классов, который описывает данные, с которыми вы работаете, а также бизнес-логику.
-
Вид — определяет, как будет отображаться пользовательский интерфейс приложения. Это чистый HTML, который решает, как будет выглядеть пользовательский интерфейс.
-
Контроллер — набор классов, который управляет связью от пользователя, общим потоком приложения и логикой приложения.
Модель — набор классов, который описывает данные, с которыми вы работаете, а также бизнес-логику.
Вид — определяет, как будет отображаться пользовательский интерфейс приложения. Это чистый HTML, который решает, как будет выглядеть пользовательский интерфейс.
Контроллер — набор классов, который управляет связью от пользователя, общим потоком приложения и логикой приложения.
Идея позади MVC
Давайте теперь поймем идею MVC.
-
Идея заключается в том, что у вас будет компонент, называемый представлением, который несет единоличную ответственность за отображение этого пользовательского интерфейса, будь то HTML или фактически виджет пользовательского интерфейса в настольном приложении.
-
Представление взаимодействует с моделью, и эта модель содержит все данные, которые необходимо отобразить.
-
В веб-приложении представление может вообще не иметь никакого кода, связанного с ним.
-
Это может быть просто HTML, а затем несколько выражений о том, где взять фрагменты данных из модели и вставить их в правильные места внутри HTML-шаблона, который вы создали в представлении.
Идея заключается в том, что у вас будет компонент, называемый представлением, который несет единоличную ответственность за отображение этого пользовательского интерфейса, будь то HTML или фактически виджет пользовательского интерфейса в настольном приложении.
Представление взаимодействует с моделью, и эта модель содержит все данные, которые необходимо отобразить.
В веб-приложении представление может вообще не иметь никакого кода, связанного с ним.
Это может быть просто HTML, а затем несколько выражений о том, где взять фрагменты данных из модели и вставить их в правильные места внутри HTML-шаблона, который вы создали в представлении.
-
Контроллер организует все. Когда HTTP-запрос поступает для приложения MVC, запрос направляется на контроллер, а затем он может связаться с базой данных, файловой системой или моделью.
Контроллер организует все. Когда HTTP-запрос поступает для приложения MVC, запрос направляется на контроллер, а затем он может связаться с базой данных, файловой системой или моделью.
В MVC контроллер получает HTTP-запрос, контроллер должен выяснить, как собрать информацию для ответа на этот запрос. Возможно, пользователь направляет браузер на URL-адрес приложения / books. Таким образом, контроллер должен собрать информацию для отображения списка книг. В этом случае контроллер будет строить модель.
-
Модель ничего не знает о HTTP-запросе или контроллере.
-
Модель отвечает только за хранение информации о книгах, которую хочет видеть пользователь, а также за любую логику, связанную с этим списком книг.
-
Модель — это просто еще один класс C #, который мы можем использовать, и у вас может быть более одного класса, если у вас сложная модель.
-
После того, как модель собрана, контроллер может выбрать представление для визуализации модели.
-
Представление получит информацию из модели, как и все книги, название каждой книги и т. Д., И будет использовать эту информацию для создания HTML-страницы.
-
Затем этот HTML-код отправляется обратно клиенту в ответе HTTP, и вся транзакция HTTP-запроса и ответа завершается.
Модель ничего не знает о HTTP-запросе или контроллере.
Модель отвечает только за хранение информации о книгах, которую хочет видеть пользователь, а также за любую логику, связанную с этим списком книг.
Модель — это просто еще один класс C #, который мы можем использовать, и у вас может быть более одного класса, если у вас сложная модель.
После того, как модель собрана, контроллер может выбрать представление для визуализации модели.
Представление получит информацию из модели, как и все книги, название каждой книги и т. Д., И будет использовать эту информацию для создания HTML-страницы.
Затем этот HTML-код отправляется обратно клиенту в ответе HTTP, и вся транзакция HTTP-запроса и ответа завершается.
Это основы шаблона проектирования MVC, и идея этого шаблона заключается в разделении интересов. Таким образом, контроллер отвечает только за принятие запроса и построение модели. Это модель, которая несет в себе логику и данные, которые нам нужны. Тогда представление отвечает только за преобразование этой модели в HTML.
ASP.NET Core — Маршрутизация
В рамках MVC у нас есть три компонента, каждый из которых сосредоточен на определенной части работы. Чтобы все это работало, нам нужно найти способ отправлять эти HTTP-запросы нужному контроллеру. В ASP.NET Core MVC этот процесс называется маршрутизацией. Маршрутизация — это процесс направления HTTP-запроса на контроллер.
Давайте теперь разберемся, как перенаправлять запросы на разные контроллеры.
-
Промежуточному программному обеспечению ASP.NET Core необходим способ определить, должен ли данный HTTP-запрос передаваться на контроллер для обработки или нет.
-
Промежуточное программное обеспечение MVC примет это решение на основе URL-адреса и предоставленной нами информации о конфигурации. В этой главе мы определим эту информацию о конфигурации или вы можете сказать информацию о маршрутизации в Startup.cs, когда мы добавим промежуточное программное обеспечение MVC.
-
Этот подход часто упоминается как основанная на соглашении маршрутизация. Ниже приведен фрагмент кода для обычной маршрутизации.
Промежуточному программному обеспечению ASP.NET Core необходим способ определить, должен ли данный HTTP-запрос передаваться на контроллер для обработки или нет.
Промежуточное программное обеспечение MVC примет это решение на основе URL-адреса и предоставленной нами информации о конфигурации. В этой главе мы определим эту информацию о конфигурации или вы можете сказать информацию о маршрутизации в Startup.cs, когда мы добавим промежуточное программное обеспечение MVC.
Этот подход часто упоминается как основанная на соглашении маршрутизация. Ниже приведен фрагмент кода для обычной маршрутизации.
routeBuilder.MapRoute("Default", "{controller=Home}/{action=Index}/{id?}");
-
В этом подходе мы определяем шаблоны, которые сообщают MVC, как искать URL-адрес и находить имя контроллера и имя действия, где контроллер — это класс C #, а действие — открытый метод для этого класса.
В этом подходе мы определяем шаблоны, которые сообщают MVC, как искать URL-адрес и находить имя контроллера и имя действия, где контроллер — это класс C #, а действие — открытый метод для этого класса.
В последней главе мы создали контроллер (HomeController) в нашем приложении, который является классом C # и не должен быть производным от базового класса или реализовывать интерфейс или иметь какой-либо специальный атрибут. Это простой класс C # с именем HomeController, и он содержит метод Index, который возвращает строку.
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace FirstAppdemo.Controllers { public class HomeController { public string Index() { return "Hello, World! this message is from Home Controller..."; } } }
Здесь мы собираемся сосредоточиться на маршрутизации на контроллеры . Мы также попытаемся понять, как работает маршрутизация.
Давайте теперь вернемся к классу Startup, где мы настроили промежуточное ПО MVC в наше приложение. Внутри метода Configure мы использовали метод UseMvcWithDefaultRoute .
public void Configure(IApplicationBuilder app) { app.UseIISPlatformHandler(); app.UseDeveloperExceptionPage(); app.UseRuntimeInfoPage(); app.UseFileServer(); app.UseMvcWithDefaultRoute(); app.Run(async (context) => { var msg = Configuration["message"]; await context.Response.WriteAsync(msg); }); }
Это дает нам правило маршрутизации по умолчанию, которое позволяет нам добраться до HomeController . Вместо использования UseMvcWithDefaultRoute , давайте использовать UseMvc , а затем настроить маршрут в этой точке, используя именованный метод ConfigureRoute . Ниже приведена реализация файла Startup.cs.
using Microsoft.AspNet.Builder; using Microsoft.AspNet.Hosting; using Microsoft.AspNet.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Configuration; using Microsoft.AspNet.Routing; using System; namespace FirstAppDemo { public class Startup { public Startup() { var builder = new ConfigurationBuilder() .AddJsonFile("AppSettings.json"); Configuration = builder.Build(); } public IConfiguration Configuration { get; set; } // This method gets called by the runtime. // Use this method to add services to the container. // For more information on how to configure your application, // visit http://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { services.AddMvc(); } // This method gets called by the runtime. // Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app) { app.UseIISPlatformHandler(); app.UseDeveloperExceptionPage(); app.UseRuntimeInfoPage(); app.UseFileServer(); app.UseMvc(ConfigureRoute); app.Run(async (context) => { var msg = Configuration["message"]; await context.Response.WriteAsync(msg); }); } private void ConfigureRoute(IRouteBuilder routeBuilder) { //Home/Index routeBuilder.MapRoute("Default", "{controller = Home}/{action = Index}/{id?}"); } // Entry point for the application. public static void Main(string[] args) => WebApplication.Run<Startup>(args); } }
Внутри метода ConfigureRoute вы можете настроить свои маршруты; Вы можете видеть, что этот метод должен принимать параметр типа IRouteBuilder. Цель маршрутизации — описать правила, которые ASP.NET Core MVC будет использовать для обработки HTTP-запроса и поиска контроллера, который может ответить на этот запрос.
-
Вы можете иметь один маршрут, который может отображать запросы на разные контроллеры.
-
Мы можем сообщить routeBuilder, что мы хотим отобразить новый маршрут, и его имя — «По умолчанию», а затем предоставить наиболее важную часть информации о маршрутизации, которая является шаблоном.
-
Шаблон представляет собой строку, и он собирается описать в ASP.NET Core MVC, как разделить URL-адрес.
-
В последнем примере мы добавили HomeController, поэтому вы также можете запросить любой из следующих URL-адресов, и они также будут направлены на действие Index на HomeController.
- HTTP: // локальный: 49940
- HTTP: // локальный: 49940 / Главная
- HTTP: // локальный: 49940 / Home / Index
-
Когда браузер запрашивает http: // mysite / или http: // mysite / Home , он возвращает выходные данные из метода Index HomeController.
-
Вы также можете попробовать это, изменив URL в браузере. В этом примере это http: // localhost: 49940 /, за исключением того, что порт может быть другим.
-
Если вы добавите / Home или / Home / Index к URL-адресу и нажмете кнопку «Ввод», вы увидите тот же результат.
-
Знак вопроса в конце идентификатора означает, что этот параметр является необязательным. Другими словами, ASP.NET Core MVC здесь не нужно видеть какой-то идентификатор, который может быть числом, строкой или GUID.
Вы можете иметь один маршрут, который может отображать запросы на разные контроллеры.
Мы можем сообщить routeBuilder, что мы хотим отобразить новый маршрут, и его имя — «По умолчанию», а затем предоставить наиболее важную часть информации о маршрутизации, которая является шаблоном.
Шаблон представляет собой строку, и он собирается описать в ASP.NET Core MVC, как разделить URL-адрес.
В последнем примере мы добавили HomeController, поэтому вы также можете запросить любой из следующих URL-адресов, и они также будут направлены на действие Index на HomeController.
Когда браузер запрашивает http: // mysite / или http: // mysite / Home , он возвращает выходные данные из метода Index HomeController.
Вы также можете попробовать это, изменив URL в браузере. В этом примере это http: // localhost: 49940 /, за исключением того, что порт может быть другим.
Если вы добавите / Home или / Home / Index к URL-адресу и нажмете кнопку «Ввод», вы увидите тот же результат.
Знак вопроса в конце идентификатора означает, что этот параметр является необязательным. Другими словами, ASP.NET Core MVC здесь не нужно видеть какой-то идентификатор, который может быть числом, строкой или GUID.
Давайте запустим приложение в браузере. После запуска приложения вы увидите следующий вывод.
Вы можете увидеть всплывающее сообщение из промежуточного программного обеспечения app.Run, и причина, по которой мы получаем это сообщение, заключается в том, что промежуточное программное обеспечение MVC увидело этот URL. Это был запрос к корню веб-сайта, который не нашел имя контроллера или имя действия в URL. Корень сайта прекратил обработку этого запроса и передал его следующему компоненту промежуточного программного обеспечения, который является кодом app.Run . Шаблон для маршрута, который мы указали, тихий в отличие от шаблона по умолчанию.
В шаблоне по умолчанию есть некоторые значения по умолчанию, которые применяются, если контроллер и имя действия не найдены. Если запрос поступает в корень сайта, именем контроллера по умолчанию будет Home. Вы можете изменить его на любой другой контроллер, если хотите, и именем действия по умолчанию может быть Index. Вы также можете изменить действие по умолчанию, если хотите, как показано в следующей программе.
private void ConfigureRoute(IRouteBuilder routeBuilder) { //Home/Index routeBuilder.MapRoute("Default", "{controller = Home}/{action = Index}/{id?}"); }
Если запрос поступает в корневой каталог веб-сайта, MVC не видит URL-адрес контроллера / действия, но может использовать эти значения по умолчанию.
Давайте сохраним файл Startup.cs и обновим браузер до корня сайта.
Теперь вы увидите ответ от вашего контроллера, и вы также можете перейти в / home, который вызовет действие по умолчанию, то есть index. Вы также можете перейти в / home / index и теперь MVC будет извлекать имя контроллера и имя действия из URL.
Давайте создадим еще один контроллер, добавив еще один класс и назовем его AboutController .
Давайте добавим несколько простых методов действия, которые будут возвращать строку, как показано в следующей программе.
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace FirstAppDemo.Controllers { public class AboutController { public string Phone() { return "+49-333-3333333"; } public string Country() { return "Germany"; } } }
В этом контроллере вы можете увидеть два метода действий — Телефон и Страна, которые будут возвращать только номер телефона и название страны соответственно. Позже мы познакомимся с модным HTML. Давайте сохраним этот файл и укажите / about / phone в конце корневого URL.
Вы можете увидеть номер телефона, как на скриншоте выше. Если вы укажете / about / country , вы также увидите название страны.
Если вы зайдете в / о , оно снова провалится через промежуточное ПО и перейдет к вашему приложению. Запустите промежуточное ПО, и вы увидите следующую страницу.
Здесь ASP.NET Core MVC переходит к AboutController, но не находит указанное действие. Таким образом, он по умолчанию будет использовать индекс, и у этого контроллера нет метода индекса, а затем запрос перейдет к следующему компоненту промежуточного программного обеспечения.
ASP.NET Core — Маршруты атрибутов
В этой главе мы изучим другой подход к маршрутизации, а именно маршрутизацию на основе атрибутов. При маршрутизации на основе атрибутов мы можем использовать атрибуты C # в наших классах контроллеров и в методах внутри этих классов. Эти атрибуты имеют метаданные, которые сообщают ASP.NET Core, когда вызывать определенный контроллер.
-
Это альтернатива обычной маршрутизации.
-
Маршруты оцениваются в том порядке, в котором они появляются, в порядке, в котором вы их регистрируете, но довольно часто можно сопоставить несколько маршрутов, особенно если вы хотите, чтобы в URL были разные параметры или если вы хотите, чтобы в URL были разные литералы.
Это альтернатива обычной маршрутизации.
Маршруты оцениваются в том порядке, в котором они появляются, в порядке, в котором вы их регистрируете, но довольно часто можно сопоставить несколько маршрутов, особенно если вы хотите, чтобы в URL были разные параметры или если вы хотите, чтобы в URL были разные литералы.
пример
Давайте возьмем простой пример. Откройте проект FirstAppDemo и запустите приложение в браузере. Когда вы укажете / about , он выдаст следующий вывод:
Здесь мы хотим, чтобы при указании / about приложение должно вызывать действие Phone в AboutController. Здесь мы можем применить некоторые явные маршруты для этого контроллера, используя атрибут Route. Этот атрибут находится в пространстве имен Microsoft.AspNet.Mvc .
Ниже приведена реализация AboutController, в которой добавляются атрибуты маршрутов.
using Microsoft.AspNet.Mvc; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace FirstAppDemo.Controllers { [Route("about")] public class AboutController { [Route ("")] public string Phone() { return "+49-333-3333333"; } [Route("country")] public string Country() { return "Germany"; } } }
Здесь мы хотим, чтобы этот маршрут выглядел примерно так, и для действия Phone мы указали пустую строку, что означает, что нам не нужно указывать действие, чтобы получить этот метод. Пользователь просто должен прийти к / о. Для действия Страна мы указали «страну» в атрибуте маршрута. Давайте сохраним AboutController, обновим ваш браузер и перейдем к / about, и он должен дать вам действие Phone.
Давайте уточним / о / страна . Это позволит вам перейти к этой стране действий.
Если вы хотите, чтобы сегмент URL-адреса содержал имя вашего контроллера, вы можете вместо использования имени контроллера явно использовать контроллер токена в квадратных скобках. Это говорит ASP.NET MVC использовать имя этого контроллера в этом положении, как показано в следующей программе.
using Microsoft.AspNet.Mvc; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace FirstAppDemo.Controllers { [Route("[controller]")] public class AboutController { [Route ("")] public string Phone() { return "+49-333-3333333"; } [Route("[action]")] public string Country() { return "Germany"; } } }
Таким образом, если вы когда-нибудь переименуете контроллер, вам не нужно будет помнить, чтобы изменить маршрут. То же самое касается действия, и неявно существует косая черта (/) между контроллером и действием. Это иерархическая связь между контроллером и действием, точно так же, как внутри URL. Давайте снова сохраним этот контроллер. Скорее всего, вы увидите те же результаты.
Давайте уточним / о / страна. Это позволит вам перейти к этой стране действий.
ASP.NET Core — результаты действий
В этой главе мы обсудим результаты действий. В предыдущих главах мы использовали простые простые классы C # в качестве контроллеров. Эти классы не являются производными от базового класса, и вы можете использовать этот подход с MVC, но более распространенным является вывод контроллера из базового класса контроллера, предоставленного в пространстве имен Microsoft.AspNet.Mvc.
-
Этот базовый класс предоставляет нам доступ к большому количеству контекстной информации о запросе, а также к методам, которые помогают нам создавать результаты для отправки обратно клиенту.
-
Вы можете отправить обратно простые строки и целые числа в ответе. Вы также можете отправить сложные объекты, такие как объект, для представления студента, университета, ресторана и т. Д., А также все данные, связанные с этим объектом.
-
Эти результаты обычно инкапсулируются в объект, который реализует интерфейс IActionResult.
-
Существует много различных типов результатов, которые реализуют этот интерфейс — типы результатов, которые могут содержать модели или содержимое файла для загрузки.
-
Эти различные типы результатов могут позволить нам отправить обратно JSON клиенту или XML или представление, которое создает HTML.
Этот базовый класс предоставляет нам доступ к большому количеству контекстной информации о запросе, а также к методам, которые помогают нам создавать результаты для отправки обратно клиенту.
Вы можете отправить обратно простые строки и целые числа в ответе. Вы также можете отправить сложные объекты, такие как объект, для представления студента, университета, ресторана и т. Д., А также все данные, связанные с этим объектом.
Эти результаты обычно инкапсулируются в объект, который реализует интерфейс IActionResult.
Существует много различных типов результатов, которые реализуют этот интерфейс — типы результатов, которые могут содержать модели или содержимое файла для загрузки.
Эти различные типы результатов могут позволить нам отправить обратно JSON клиенту или XML или представление, которое создает HTML.
Действия в основном возвращают различные типы результатов действий. Класс ActionResult является базой для всех результатов действия. Ниже приведен список различных видов результатов действий и их поведения.
название | Поведение |
---|---|
ContentResult | Возвращает строку |
FileContentResult | Возвращает содержимое файла |
FilePathResult | Возвращает содержимое файла |
FileStreamResult | Возвращает содержимое файла. |
EmptyResult | Ничего не возвращает |
JavaScriptResult | Возвращает скрипт для исполнения |
JsonResult | Возвращает данные в формате JSON |
RedirectToResult | Перенаправляет на указанный URL |
HttpUnauthorizedResult | Возвращает код состояния HTTP 403 |
RedirectToRouteResult | Перенаправление на другое действие / другое действие контроллера |
ViewResult | Получен в качестве ответа для просмотра движка |
PartialViewResult | Получен в качестве ответа для просмотра движка |
Пример 1
Давайте выполним простой пример, открыв класс HomeController и выведя его из класса, основанного на контроллере. Этот базовый класс находится в пространстве имен Microsoft.AspNet.Mvc . Ниже приведена реализация класса HomeController.
using Microsoft.AspNet.Mvc; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace FirstAppdemo.Controllers { public class HomeController : Controller { public ContentResult Index() { return Content("Hello, World! this message is from Home Controller using the Action Result"); } } }
Теперь вы можете видеть, что метод index возвращает ContentResult, который является одним из типов результатов, и все эти типы результатов в конечном итоге реализуют интерфейс, который является ActionResult .
В методе Index мы передали строку в метод Content. Этот метод Content создает ContentResult; это означает, что метод Index теперь будет возвращать ContentResult .
Давайте сохраним класс HomeController и запустим приложение в браузере. Будет произведена следующая страница.
Теперь вы можете увидеть ответ, который ничем не отличается от ответа, который мы имели раньше. Это все еще будет простой текстовый ответ.
-
Вам может быть интересно, каково преимущество использования чего-то, что создает ActionResult .
-
Типичное преимущество заключается в том, что это просто формальный способ инкапсулировать решение контроллера.
-
Контроллер решает, что делать дальше: либо вернуть строку или HTML, либо вернуть объект модели, который может быть сериализован в JSON и т. Д.
-
Все, что нужно сделать контроллеру, — это принять это решение, и контроллеру не нужно прямо записывать в ответ результаты своего решения.
-
Нужно просто вернуть решение, и тогда это среда, которая возьмет результат и поймет, как преобразовать этот результат во что-то, что может быть отправлено обратно по HTTP.
Вам может быть интересно, каково преимущество использования чего-то, что создает ActionResult .
Типичное преимущество заключается в том, что это просто формальный способ инкапсулировать решение контроллера.
Контроллер решает, что делать дальше: либо вернуть строку или HTML, либо вернуть объект модели, который может быть сериализован в JSON и т. Д.
Все, что нужно сделать контроллеру, — это принять это решение, и контроллеру не нужно прямо записывать в ответ результаты своего решения.
Нужно просто вернуть решение, и тогда это среда, которая возьмет результат и поймет, как преобразовать этот результат во что-то, что может быть отправлено обратно по HTTP.
Пример 2
Давайте возьмем другой пример. Создайте новую папку в проекте и назовите ее « Модели» . Внутри папки Models мы хотим добавить класс, который может представлять Employee.
Введите Employee.cs в поле Имя, как на скриншоте выше. Здесь реализация класса Employee содержит два свойства.
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace FirstAppDemo.Models { public class Employee { public int ID { get; set; } public string Name { get; set} } }
Внутри метода действия Index HomeController мы хотим вернуть объект Employee. Ниже приведена реализация HomeController.
using FirstAppDemo.Models; using Microsoft.AspNet.Mvc; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace FirstAppdemo.Controllers { public class HomeController : Controller { public ObjectResult Index() { var employee = new Employee { ID = 1, Name = "Mark Upston"}; return new ObjectResult(employee); } } }
Теперь вместо того, чтобы возвращать содержимое, мы будем возвращать другой тип результата, который известен как ObjectResult . Если нам нужен ObjectResult, нам нужно создать или создать экземпляр ObjectResult и передать в него некоторый объект модели .
-
ObjectResult является особенным в среде MVC, потому что когда мы возвращаем ObjectResult, среда MVC смотрит на этот объект. Этот объект должен быть представлен в ответе HTTP.
-
Этот объект должен быть сериализован в XML, JSON или другой формат, и в конечном итоге решение будет принято на основе информации о конфигурации, которую вы передаете MVC при запуске. Если вы ничего не настраиваете, вы просто получаете некоторые значения по умолчанию, и по умолчанию используется ответ JSON.
ObjectResult является особенным в среде MVC, потому что когда мы возвращаем ObjectResult, среда MVC смотрит на этот объект. Этот объект должен быть представлен в ответе HTTP.
Этот объект должен быть сериализован в XML, JSON или другой формат, и в конечном итоге решение будет принято на основе информации о конфигурации, которую вы передаете MVC при запуске. Если вы ничего не настраиваете, вы просто получаете некоторые значения по умолчанию, и по умолчанию используется ответ JSON.
Сохраните все свои файлы и обновите браузер. Вы увидите следующий вывод.
ASP.NET Core — Просмотров
В приложении ASP.NET Core MVC нет ничего похожего на страницу, и оно также не содержит ничего, что непосредственно соответствует странице, когда вы указываете путь в URL. Самая близкая вещь к странице в приложении ASP.NET Core MVC известна как представление.
-
Как вы знаете, в приложении ASP.NET MVC все входящие запросы браузера обрабатываются контроллером, и эти запросы отображаются на действия контроллера.
-
Действие контроллера может возвращать представление или также может выполнять какое-либо другое действие, например перенаправление на другое действие контроллера.
-
В среде MVC наиболее популярным методом создания HTML является использование механизма представления Razor в ASP.NET MVC.
-
Чтобы использовать этот механизм представления, действие контроллера создает объект ViewResult , и ViewResult может содержать имя представления Razor, которое мы хотим использовать.
Как вы знаете, в приложении ASP.NET MVC все входящие запросы браузера обрабатываются контроллером, и эти запросы отображаются на действия контроллера.
Действие контроллера может возвращать представление или также может выполнять какое-либо другое действие, например перенаправление на другое действие контроллера.
В среде MVC наиболее популярным методом создания HTML является использование механизма представления Razor в ASP.NET MVC.
Чтобы использовать этот механизм представления, действие контроллера создает объект ViewResult , и ViewResult может содержать имя представления Razor, которое мы хотим использовать.
-
Представление будет файлом в файловой системе, и ViewResult может также переносить объект модели к представлению, и представление может использовать этот объект модели при создании HTML.
-
Когда инфраструктура MVC видит, что действие вашего контроллера создает ViewResult, платформа найдет представление в файловой системе, выполнит представление, которое создает HTML, и именно этот HTML-код платформа отправляет обратно клиенту.
Представление будет файлом в файловой системе, и ViewResult может также переносить объект модели к представлению, и представление может использовать этот объект модели при создании HTML.
Когда инфраструктура MVC видит, что действие вашего контроллера создает ViewResult, платформа найдет представление в файловой системе, выполнит представление, которое создает HTML, и именно этот HTML-код платформа отправляет обратно клиенту.
пример
Давайте теперь возьмем простой пример, чтобы понять, как это работает в нашем приложении, изменив реализацию метода индекса HomeController, как показано в следующей программе.
using FirstAppDemo.Models; using Microsoft.AspNet.Mvc; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace FirstAppdemo.Controllers { public class HomeController : Controller { public ViewResult Index() { var employee = new Employee { ID = 1, Name = "Mark Upston"}; return View(); } } }
Внутри HomeController вместо создания ObjectResult давайте просто вернем то, что возвращает метод View () . Метод View не возвращает ObjectResult. Он создает новый ViewResult, поэтому мы также изменим тип возврата метода Index на ViewResult. Метод View принимает некоторые параметры здесь. Мы вызовем этот метод без каких-либо других параметров. Позвольте нам сохранить ваш файл и обновить ваш браузер.
Это связано с тем, что MVC-фреймворк должен выйти и найти это представление, но сейчас его нет.
-
Представления по умолчанию в проекте C # ASP.NET — это файлы с расширением * .cshtml, и представления следуют определенному соглашению. По умолчанию все представления находятся в папке представлений в проекте.
-
Расположение представления и имя файла представления будут получены ASP.NET MVC, если вы не предоставите ему никакой дополнительной информации.
-
Если нам нужно отобразить представление из действия Index HomeController, первое место, которое MVC-среда будет искать для этого представления, находится внутри папки Views.
-
Он перейдет в домашнюю папку и затем найдет файл Index.cshtml — имя файла начинается с Index, потому что мы находимся в действии Index.
-
Среда MVC также будет искать в общей папке и представлениях, которые вы помещаете в общую папку, вы можете использовать их в любом месте приложения.
Представления по умолчанию в проекте C # ASP.NET — это файлы с расширением * .cshtml, и представления следуют определенному соглашению. По умолчанию все представления находятся в папке представлений в проекте.
Расположение представления и имя файла представления будут получены ASP.NET MVC, если вы не предоставите ему никакой дополнительной информации.
Если нам нужно отобразить представление из действия Index HomeController, первое место, которое MVC-среда будет искать для этого представления, находится внутри папки Views.
Он перейдет в домашнюю папку и затем найдет файл Index.cshtml — имя файла начинается с Index, потому что мы находимся в действии Index.
Среда MVC также будет искать в общей папке и представлениях, которые вы помещаете в общую папку, вы можете использовать их в любом месте приложения.
Чтобы результаты нашего просмотра работали правильно, давайте создадим этот файл Index.cshtml в правильном месте. Поэтому в нашем проекте нам сначала нужно добавить папку, которая будет содержать все наши представления, и назвать ее Views. Внутри папки Views мы добавим еще одну папку для представлений, связанных с нашим HomeController, и назовем эту папку Home. Щелкните правой кнопкой мыши домашнюю папку и выберите « Добавить» → « Новый элемент» .
На левой панели выберите страницу просмотра MVC, введите index.cshtml в поле имени и нажмите кнопку «Добавить».
Давайте добавим следующий код в файл index.cshtml.
<html xmlns = "http://www.w3.org/1999/xhtml"> <head> <title>Home</title> </head> <body> <h1>Welcome!</h1> <div> This message is from the View... </div> </body> </html>
Теперь вы можете увидеть файл * .cshtml . Он может содержать разметку HTML, и любая разметка, которая у нас есть в этом файле, будет отправлена непосредственно клиенту. Сохраните этот файл и обновите ваш браузер.
Теперь контроллер Home через ViewResult предоставил это представление клиенту и всей разметке, которая находится в этом файле index.cshtml, то есть, что было отправлено клиенту.
Давайте вернемся к HomeController и методу View. Этот метод View имеет несколько различных перегрузок и передает модель сотрудника в качестве параметра.
using FirstAppDemo.Models; using Microsoft.AspNet.Mvc; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace FirstAppdemo.Controllers { public class HomeController : Controller { public ViewResult Index() { var employee = new Employee { ID = 1, Name = "Mark Upston"}; return View(employee); } } }
Метод View, который просто берет объект модели и использует представление по умолчанию, а именно Index. Здесь мы просто хотим передать информацию об этой модели и использовать эту модель внутри Index.cshtml, как показано в следующей программе.
<html xmlns = "http://www.w3.org/1999/xhtml"> <head> <title>Home</title> </head> <body> <h1>Welcome!</h1> <div> @Model.Name </div> </body> </html>
Когда мы используем знак @ в представлении Razor , движок представления Razor будет обрабатывать все, что вы вводите, как выражение C #. Razor view содержит некоторые встроенные члены, к которым мы можем получить доступ в выражениях C #. Одним из наиболее важных членов является Модель. Когда вы говорите @Model, вы получите объект модели, который вы передали в представление из контроллера. Так что здесь @ Model.Name будет отображать имя сотрудника внутри представления.
Давайте теперь сохраним все файлы. После этого обновите браузер, чтобы увидеть следующий вывод.
Теперь вы можете увидеть имя сотрудника, как на скриншоте выше.
ASP.NET Core — Настройка Entity Framework
В этой главе мы настроим и настроим наше приложение для сохранения и чтения данных из базы данных SQL Server.
Для работы с базой данных мы будем использовать Entity Framework, который был недавно переписан для работы с новым .NET Framework. Если вы работали с EF в прошлом, вы увидите много знакомых частей.
-
В этом приложении мы будем использовать SQL Server LocalDB. Если вас не устраивает SQL Server, вы можете использовать любую базу данных, которая вам нравится, такую как локальная база данных, удаленная база данных, если у вас есть разрешение на создание новой базы данных на экземпляре.
-
LocalDB — это специальная версия SQL Server, оптимизированная для разработчиков.
-
Visual Studio 2015 и даже ее редакция Community будут устанавливать LocalDB по умолчанию.
В этом приложении мы будем использовать SQL Server LocalDB. Если вас не устраивает SQL Server, вы можете использовать любую базу данных, которая вам нравится, такую как локальная база данных, удаленная база данных, если у вас есть разрешение на создание новой базы данных на экземпляре.
LocalDB — это специальная версия SQL Server, оптимизированная для разработчиков.
Visual Studio 2015 и даже ее редакция Community будут устанавливать LocalDB по умолчанию.
Чтобы проверить LocalDB, перейдите в пункт меню View → SQL Server Object Explorer в Visual Studio.
Это отличный инструмент, если вам нужно работать с SQL Server, потому что он позволяет вам исследовать базы данных, просматривать данные и даже создавать данные внутри базы данных. Когда вы впервые откроете его, это может занять некоторое время, но он должен автоматически подключиться к LocalDB.
Установить Entity Framework
Первым шагом в использовании Entity Framework является установка пакета NuGet Entity Framework из диспетчера пакетов NuGet или путем непосредственного редактирования файла project.json .
Давайте теперь отредактируем файл project.json напрямую, добавив следующие два пакета.
Пакет EntityFramework.Commands помогает нам выполнять задачи с Entity Framework, такие как создание схемы базы данных на основе наших классов C # Entity, и эти задачи доступны из инструмента командной строки, где логика находится внутри пакета EntityFramework.Commands.
Чтобы использовать этот инструмент командной строки, нам нужно сделать дополнительную запись в разделе команд файла project.json, как показано на следующем снимке экрана.
Мы только что назвали его «ef», и это будет соответствовать этому пакету EntityFramework.Commands. Мы можем использовать этот «ef», чтобы получить доступ к некоторой логике, которая доступна внутри EntityFramework.Commands.
Ниже приведена реализация файла project.json.
{ "version": "1.0.0-*", "compilationOptions": { "emitEntryPoint": true }, "dependencies": { "Microsoft.AspNet.Mvc": "6.0.0-rc1-final", "Microsoft.AspNet.Diagnostics": "1.0.0-rc1-final", "Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final", "Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final", "Microsoft.AspNet.StaticFiles": "1.0.0-rc1-final", "EntityFramework.MicrosoftSqlServer": "7.0.0-rc1-final", "EntityFramework.Commands": "7.0.0-rc1-final" } "commands": { "web": "Microsoft.AspNet.Server.Kestrel" }, "frameworks": { "dnx451": { }, "dnxcore50": { } }, "exclude": [ "wwwroot", "node_modules" ], "publishExclude": [ "**.user", "**.vspscc" ] }
ASP.NET Core — DBContext
Entity Framework позволяет запрашивать, вставлять, обновлять и удалять данные, используя объекты Common Language Runtime (CLR), известные как сущности. Entity Framework отображает сущности и отношения, которые определены в вашей модели, в базу данных. Он также предоставляет возможности для —
-
Материализуйте данные, возвращаемые из базы данных как объекты сущностей.
-
Отслеживайте изменения, которые были внесены в объекты.
-
Обрабатывать параллелизм.
-
Распространение объекта изменений обратно в базу данных.
-
Привязать объекты к элементам управления.
Материализуйте данные, возвращаемые из базы данных как объекты сущностей.
Отслеживайте изменения, которые были внесены в объекты.
Обрабатывать параллелизм.
Распространение объекта изменений обратно в базу данных.
Привязать объекты к элементам управления.
Основным классом, который отвечает за взаимодействие с данными как объектами, является DbContext. Рекомендуемый способ работы с контекстом — определить класс, производный от DbContext и раскрывающий свойства DbSet, которые представляют коллекции указанных объектов в контексте.
Логически DBContext сопоставляется с конкретной базой данных, которая имеет схему, которую DBContext понимает. И в этом классе DBContext вы можете создавать свойства типа DbSet <T>. Параметр универсального типа T будет типом сущности, как Employee — сущность в приложении FirstAppDemo.
пример
Давайте рассмотрим простой пример, в котором мы создадим класс DbContext. Здесь нам нужно добавить новый класс в папку Models и назвать его FirstAppDempDbContext . Хотя этот класс не является моделью сам по себе, он объединяет все наши модели, чтобы мы могли использовать их с базой данных.
Унаследуйте свой контекстный класс от класса DbContext, который находится в пространстве имен Miscrosoft.Data.Entity. Теперь реализуем DbSet Employee для этого класса.
Каждый DbSet будет сопоставлен с таблицей в базе данных. Если у вас есть свойство DbSet сотрудника, и имя этого свойства — «Сотрудники», Entity Framework по умолчанию будет искать таблицу «Сотрудники» в вашей базе данных.
using FirstAppDemo.Models; using Microsoft.Data.Entity; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace OdeToFood.Models { public class FirstAppDemoDbContext : DbContext { public DbSet<Employee> Employees { get; set; } } }
Реализация очень проста, потому что у нас есть только одна модель для работы. Нам нужно только одно свойство, DbSet of Employee, и мы можем назвать это свойство Employees .
Теперь давайте вставим этот класс непосредственно в контроллеры, и затем контроллеры смогут использовать FirstAppDemoDbContext для запроса базы данных. Мы упростим все это, добавив новый класс в класс HomeController, в котором мы реализуем методы для добавления сотрудников и получения сотрудников, как показано в следующей программе.
using Microsoft.AspNet.Mvc; using FirstAppDemo.ViewModels; using FirstAppDemo.Services; using FirstAppDemo.Entities; using FirstAppDemo.Models; using System.Collections.Generic; using System.Linq; namespace FirstAppDemo.Controllers { public class HomeController : Controller { public ViewResult Index() { var model = new HomePageViewModel(); using (var context = new FirstAppDemoDbContext()) { SQLEmployeeData sqlData = new SQLEmployeeData(context); model.Employees = sqlData.GetAll(); } return View(model); } } public class SQLEmployeeData { private FirstAppDemoDbContext _context { get; set; } public SQLEmployeeData(FirstAppDemoDbContext context) { _context = context; } public void Add(Employee emp) { _context.Add(emp); _context.SaveChanges(); } public Employee Get(int ID) { return _context.Employees.FirstOrDefault(e => e.Id == ID); } public IEnumerable<Employee> GetAll() { return _context.Employees.ToList<Employee>(); } } public class HomePageViewModel { public IEnumerable<Employee> Employees { get; set; } } }
В приведенном выше классе SQLEmployeeData вы можете видеть, что мы определили метод Add, который добавит новый объект employee в контекст, а затем сохранит изменения. В методе Get он возвращает сотрудника на основе идентификатора. Принимая во внимание, что в методе GetAll он вернет список всех сотрудников в базе данных.
Настройка служб Entity Framework
Чтобы иметь пригодный для использования Entity Framework DBContext, нам нужно изменить конфигурацию приложения. Нам нужно будет добавить строку подключения, чтобы наш DBContext знал, к какому серверу обращаться и какую базу данных запрашивать.
-
Мы поместим строку подключения в файл конфигурации JSON.
-
Нам также нужно добавить еще несколько сервисов во время метода ConfigureServices класса Startup.
-
Entity Framework, так же как ASP.NET и MVC Framework, Entity Framework опирается на внедрение зависимостей, и для внедрения необходимо, чтобы среда выполнения знала о различных сервисах, которые использует Entity Framework.
-
Существует простой API настройки, который добавит все необходимые нам службы по умолчанию.
Мы поместим строку подключения в файл конфигурации JSON.
Нам также нужно добавить еще несколько сервисов во время метода ConfigureServices класса Startup.
Entity Framework, так же как ASP.NET и MVC Framework, Entity Framework опирается на внедрение зависимостей, и для внедрения необходимо, чтобы среда выполнения знала о различных сервисах, которые использует Entity Framework.
Существует простой API настройки, который добавит все необходимые нам службы по умолчанию.
Давайте перейдем к файлу AppSettings.json и добавим строку соединений, как показано в следующей программе.
{ "message": "Hello, World! this message is from configuration file...", "database": { "connection": "Data Source=(localdb)\\mssqllocaldb;Initial Catalog=FirstAppDemo" } }
Теперь давайте перейдем к классу Startup, где нам нужно добавить некоторые дополнительные службы для правильной работы Entity Framework. В частности, есть три вещи, которые нам нужно сделать, которые связаны с Entity Framework —
-
Нам нужно добавить основные службы Entity Framework.
-
Нам также необходимо добавить службы Entity Framework, связанные с SQL Server.
-
Нам нужно рассказать Entity Framework о нашем DBContext.
Нам нужно добавить основные службы Entity Framework.
Нам также необходимо добавить службы Entity Framework, связанные с SQL Server.
Нам нужно рассказать Entity Framework о нашем DBContext.
Все это можно сделать с помощью методов, которые доступны в качестве методов расширения на IServiceCollection, как показано в следующей программе.
public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddEntityFramework() .AddSqlServer() .AddDbContext<FirstAppDemoDbContext> (option => option.UseSqlServer(Configuration["database:connection"])); }
-
Первый метод — AddEntityFramework . Это добавит основные службы Entity Framework, службы по умолчанию.
-
Но поскольку Entity Framework теперь предназначена для работы с различными типами баз данных, включая нереляционные базы данных, нам нужно сделать второй вызов, чтобы сообщить Entity Framework, что нужно добавить свои службы, связанные с SQL Server по умолчанию.
-
Затем нам также нужно сообщить Entity Framework о моем классе DBContext, чтобы он мог соответствующим образом создавать экземпляры этого класса, и мы можем сделать это с помощью третьего метода, метода AddDbContext .
-
Этот параметр принимает параметр общего типа, в котором мы указываем тип производного класса DBContext, FirstAppDemoDbContext .
-
Внутри AddDbContext нам нужно описать опции для нашего DBContext.
-
Это можно сделать с помощью лямбда-выражения ; это действие, при котором мы получаем параметр option, а Entity Framework может поддерживать разные базы данных. Все, что нам нужно сделать, это сообщить Entity Framework, что этот конкретный DBContext собирается использовать UseSqlServer .
-
Этот метод требует параметр, который является connectionString для использования.
Первый метод — AddEntityFramework . Это добавит основные службы Entity Framework, службы по умолчанию.
Но поскольку Entity Framework теперь предназначена для работы с различными типами баз данных, включая нереляционные базы данных, нам нужно сделать второй вызов, чтобы сообщить Entity Framework, что нужно добавить свои службы, связанные с SQL Server по умолчанию.
Затем нам также нужно сообщить Entity Framework о моем классе DBContext, чтобы он мог соответствующим образом создавать экземпляры этого класса, и мы можем сделать это с помощью третьего метода, метода AddDbContext .
Этот параметр принимает параметр общего типа, в котором мы указываем тип производного класса DBContext, FirstAppDemoDbContext .
Внутри AddDbContext нам нужно описать опции для нашего DBContext.
Это можно сделать с помощью лямбда-выражения ; это действие, при котором мы получаем параметр option, а Entity Framework может поддерживать разные базы данных. Все, что нам нужно сделать, это сообщить Entity Framework, что этот конкретный DBContext собирается использовать UseSqlServer .
Этот метод требует параметр, который является connectionString для использования.
Ниже приведена полная реализация файла Startup.cs .
using Microsoft.AspNet.Mvc; using FirstAppDemo.ViewModels; using FirstAppDemo.Services; using FirstAppDemo.Entities; using FirstAppDemo.Models; using System.Collections.Generic; using System.Linq; namespace FirstAppDemo.Controllers { public class HomeController : Controller { public ViewResult Index() { var employee = new Employee { Id = 1, Name = "Mark Upston1" }; using (var context = new FirstAppDemoDbContext()) { SQLEmployeeData sqlData = new SQLEmployeeData(context); sqlData.Add(employee); } //var employee = new Employee { ID = 1, Name = "Mark Upston" }; return View(employee); } } public class SQLEmployeeData { private FirstAppDemoDbContext _context { get; set; } public SQLEmployeeData(FirstAppDemoDbContext context) { _context = context; } public void Add(Employee emp) { _context.Add(emp); _context.SaveChanges(); } public Employee Get(int ID) { return _context.Employees.FirstOrDefault(e => e.Id == ID); } public IEnumerable<Employee> GetAll() { return _context.Employees.ToList<Employee>(); } } }
Теперь нам нужно настроить базу данных. Один из способов настроить базу данных — использовать Entity Framework для создания базы данных, и это двухэтапный процесс —
Первый шаг
Это включает в себя следующее —
-
Добавление кода миграции в наш проект.
-
Код миграции — это код C # . Это может быть выполнено для создания базы данных в схеме базы данных.
-
Entity Framework может сгенерировать этот код миграции для нас.
-
Entity Framework просматривает базу данных и наши модели и выясняет, какие изменения схемы необходимы для работы приложения.
-
Поэтому, когда мы добавляем дополнительные модели или вносим изменения в существующие модели, такие как класс Employee, мы можем продолжать добавлять миграции в наш проект и поддерживать синхронизацию нашей схемы базы данных.
Добавление кода миграции в наш проект.
Код миграции — это код C # . Это может быть выполнено для создания базы данных в схеме базы данных.
Entity Framework может сгенерировать этот код миграции для нас.
Entity Framework просматривает базу данных и наши модели и выясняет, какие изменения схемы необходимы для работы приложения.
Поэтому, когда мы добавляем дополнительные модели или вносим изменения в существующие модели, такие как класс Employee, мы можем продолжать добавлять миграции в наш проект и поддерживать синхронизацию нашей схемы базы данных.
Второй Шаг
Это включает в себя следующее —
-
Здесь нам нужно явно применить эти миграции для обновления базы данных.
-
Обе эти задачи могут быть выполнены с помощью некоторых простых команд из окна консоли.
-
Мы сделали project.json.
-
Вот почему мы создали project.json для добавления команды, в которой «ef» отображается на EntityFramework.Commands.
Здесь нам нужно явно применить эти миграции для обновления базы данных.
Обе эти задачи могут быть выполнены с помощью некоторых простых команд из окна консоли.
Мы сделали project.json.
Вот почему мы создали project.json для добавления команды, в которой «ef» отображается на EntityFramework.Commands.
Давайте откроем командную строку разработчика для Visual Studio, чтобы запустить команды, необходимые для добавления миграций и применения миграций. Самый простой способ сделать это — перейти в корневой каталог приложения.
Если вы находитесь в папке с файлом project.json, значит, вы находитесь в правильной папке. Здесь нам нужно выполнить команду, известную как dnvm. Это менеджер версий .NET, который сообщит системе, какое время выполнения мы хотим использовать.
Давайте теперь воспользуемся следующей командой.
dnvm list
Вы увидите следующий вывод при нажатии Enter.
Нам нужно сообщить dnvm, что мы хотим использовать определенные среды выполнения. Это даст нам доступ к команде dotnet или команде dnx, которую мы хотим выполнить.
Выполните следующую команду.
dnvm use1.0.0-rc1-update1 -p
Нажмите Ввод.
dnvm настроит наш путь и переменные среды для включения каталога bin, который даст нам доступ к этой утилите dnx. Давайте выполним команду dnx ef .
Это среда исполнения .NET, с помощью dnx мы можем вызывать команды, которые мы перечислили в нашем файле project.json. Выполнение этих команд обычно очень просто. Когда вы наберете dnx ef, вы получите экран справки. Вам не нужно помнить все варианты. Вы можете увидеть доступные команды в Entity Framework Commands, и их три.
Сначала нам нужно добавить миграцию для выполнения следующей команды.
dnx ef migrations add v1
Нажмите Ввод.
Entity Framework найдет этот контекст и рассмотрит модели, которые находятся внутри. Он будет знать, что предыдущей миграции нет, и поэтому он будет генерировать первую миграцию. Здесь v1 является версией 1 базы данных. Он создаст новую папку в обозревателе решений и сгенерирует код.
Миграция — это, по сути, код C #, который используется для генерации команд SQL для изменения схемы в базе данных SQL.
using System; using System.Collections.Generic; using Microsoft.Data.Entity.Migrations; using Microsoft.Data.Entity.Metadata; namespace FirstAppDemo.Migrations { public partial class v1 : Migration { protected override void Up(MigrationBuilder migrationBuilder) { migrationBuilder.CreateTable(name: "Employee", columns: table => new { Id = table.Column<int>(nullable: false) .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), Name = table.Column<string>(nullable: true) }, constraints: table => { table.PrimaryKey("PK_Employee", x => x.Id); }); } protected override void Down(MigrationBuilder migrationBuilder) { migrationBuilder.DropTable("Employee"); } } }
Вы можете видеть, что он создаст таблицу с именем Employees.
-
Эта таблица должна иметь два столбца — идентификатор и столбец имени.
-
По соглашению, когда Entity Framework увидит, что у вас есть свойство с именем Id, оно сделает это свойство или, скорее, сделает этот столбец первичным ключом в базе данных.
-
Здесь мы будем использовать SQL Server. По умолчанию Entity Framework делает это IdentityColumn, что означает, что SQL Server будет генерировать идентификаторы для нас.
Эта таблица должна иметь два столбца — идентификатор и столбец имени.
По соглашению, когда Entity Framework увидит, что у вас есть свойство с именем Id, оно сделает это свойство или, скорее, сделает этот столбец первичным ключом в базе данных.
Здесь мы будем использовать SQL Server. По умолчанию Entity Framework делает это IdentityColumn, что означает, что SQL Server будет генерировать идентификаторы для нас.
Давайте применим эти идентификаторы к базе данных, набрав команду « dnx ef database update ».
Вы можете видеть, что команда применила миграцию.
Теперь давайте перейдем к Обозревателю объектов SQL Server и обновим базы данных. Теперь вы можете видеть, что у нас есть база данных FirstAppDemo.
Вы также можете увидеть нашу таблицу Employee, и мы даже можем посмотреть на столбцы для этой таблицы, в которой столбец ID является первичным ключом.
Давайте щелкните правой кнопкой мыши по таблице dbo.Employee и выберите «Просмотр данных».
Прежде чем запустить приложение, давайте добавим некоторые данные. Когда мы запускаем приложение, мы должны увидеть некоторые данные из базы данных.
Давайте просто добавим пару строк данных здесь.
Давайте теперь обновим файл index.cshtml. Он показывает все данные в табличной форме.
@model FirstAppDemo.Controllers.HomePageViewModel <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Home</title> </head> <body> <h1>Welcome!</h1> <table> @foreach (var employee in Model.Employees) { <tr> <td> @Html.ActionLink(employee.Id.ToString(), "Details", new { id = employee.Id }) </td> <td>@employee.Name</td> </tr> } </table> </body> </html>
Как только вы запустите приложение, оно должно выдать следующий результат.
ASP.NET Core — виды раскладки бритвы
В этой главе мы разберем виды раскладки бритвы. Большинство веб-сайтов и веб-приложений захотят создавать страницы, которые представляют некоторые общие элементы.
-
У вас обычно есть верхняя область на каждой странице, где вы отображаете логотип и навигационное меню.
-
У вас также может быть боковая панель с дополнительными ссылками и информацией и, возможно, нижний колонтитул в нижней части страницы с некоторым содержанием.
-
Каждая страница приложения будет хотеть иметь эти общие факторы. Здесь мы используем представление «Макет», чтобы избежать дублирования факторов на каждой странице, которую мы пишем.
У вас обычно есть верхняя область на каждой странице, где вы отображаете логотип и навигационное меню.
У вас также может быть боковая панель с дополнительными ссылками и информацией и, возможно, нижний колонтитул в нижней части страницы с некоторым содержанием.
Каждая страница приложения будет хотеть иметь эти общие факторы. Здесь мы используем представление «Макет», чтобы избежать дублирования факторов на каждой странице, которую мы пишем.
Макет просмотра
Давайте теперь поймем, что такое Layout View.
-
Представление Layout — это представление Razor с расширением * .cshtml . У вас есть выбор назвать макет так, как вы хотите. В этой главе мы будем использовать представление Layout с именем _Layout.cshtml .
-
Это общее имя для представления макета, и начальное подчеркивание не требуется. Это просто соглашение, которому следуют многие разработчики для определения представления, которое не является представлением; Вы визуализируете это как результат просмотра от действия контроллера.
-
Это особый вид, но как только у нас будет представление «Макет», мы можем настроить наши представления контроллера, такие как представление «Индекс» для домашней страницы.
Представление Layout — это представление Razor с расширением * .cshtml . У вас есть выбор назвать макет так, как вы хотите. В этой главе мы будем использовать представление Layout с именем _Layout.cshtml .
Это общее имя для представления макета, и начальное подчеркивание не требуется. Это просто соглашение, которому следуют многие разработчики для определения представления, которое не является представлением; Вы визуализируете это как результат просмотра от действия контроллера.
Это особый вид, но как только у нас будет представление «Макет», мы можем настроить наши представления контроллера, такие как представление «Индекс» для домашней страницы.
-
Мы можем настроить этот вид для рендеринга внутри макета в определенном месте.
-
Такой подход к представлению макета означает, что Index.cshtml не нужно ничего знать о логотипе или навигации верхнего уровня.
-
Представление Index должно отображать только конкретный контент для модели, которую действие контроллера дает этому представлению, а представление Layout позаботится обо всем остальном.
Мы можем настроить этот вид для рендеринга внутри макета в определенном месте.
Такой подход к представлению макета означает, что Index.cshtml не нужно ничего знать о логотипе или навигации верхнего уровня.
Представление Index должно отображать только конкретный контент для модели, которую действие контроллера дает этому представлению, а представление Layout позаботится обо всем остальном.
пример
Давайте возьмем простой пример.
Если у вас есть несколько представлений, то вы увидите, что все представления будут содержать некоторое количество повторяющейся разметки. Все они будут иметь открывающий тег HTML, тег head и тег body .
Даже если у нас нет навигационного меню в этом приложении, есть вероятность, что в реальном приложении оно также может быть доступно, и мы не хотим дублировать эту разметку в каждом представлении.
Давайте создадим представление Layout, и мы добавим представление Layout в новую папку с именем Shared внутри папки Views . Это обычная папка, о которой знает инфраструктура MVC. Он знает, что представления внутри здесь могут использоваться несколькими контроллерами в приложении. Давайте щёлкнем правой кнопкой мыши по папке Shared и выберите Add → New Item.
На средней панели выберите страницу макета представления MVC. Имя по умолчанию здесь _Layout.cshtml. Выберите представление Layout, которое вы хотите использовать во время выполнения, в зависимости от пользователя. Теперь нажмите на кнопку Добавить. Это то, что вы получите по умолчанию для вашего нового вида Layout.
Мы хотим, чтобы представление Layout отвечало за управление головой и телом. Теперь, когда это представление находится в представлении Razor, мы можем использовать выражения C #. Мы все еще можем добавить буквальный текст. Теперь у нас есть div, который отображает DateTime.Now. Давайте теперь просто добавим год.
<!DOCTYPE html> <html> <head> <meta name = "viewport" content = "width = device-width" /> <title>@ViewBag.Title</title> </head> <body> <div> @DateTime.Now </div> <div> @RenderBody() </div> </body> </html>
В приведенном выше коде вы увидите такие выражения, как RenderBody и ViewBag.Title . Когда действие контроллера MVC отображает представление «Индекс», и с ним включается страница макета; тогда представление индекса и созданный им HTML-код будут помещены в представление индекса.
Это где вызов метода для RenderBody существует. Мы можем ожидать, что все представления контента в нашем приложении появятся внутри div, где вызывается RenderBody.
Другое выражение внутри этого файла — ViewBag.Title. ViewBag — это структура данных, которую можно добавить к любому свойству и любым данным, которые вы хотите добавить в ViewBag. Мы можем добавить ViewBag.Title, ViewBag.CurrentDate или любые свойства, которые мы хотим в ViewBag.
Теперь перейдем к файлу index.cshtml.
@model FirstAppDemo.Controllers.HomePageViewModel <html xmlns = "http://www.w3.org/1999/xhtml"> <head> <title>Home</title> </head> <body> <h1>Welcome!</h1> <table> @foreach (var employee in Model.Employees) { <tr> <td> @Html.ActionLink(employee.Id.ToString(), "Details", new { id = employee.Id }) </td> <td>@employee.Name</td> </tr> } </table> </body> </html>
Удалите разметку, которая нам больше не нужна, в представлении индекса. Таким образом, мы можем удалить такие вещи, как тег HTML и тег head. Нам также не нужен открывающий элемент body или закрывающие теги, как показано в следующей программе.
@model FirstAppDemo.Controllers.HomePageViewModel @{ ViewBag.Title = "Home"; Layout = "~/Views/Shared/_Layout.cshtml"; } <h1>Welcome!</h1> <table> @foreach (var employee in Model.Employees) { <tr> <td> @Html.ActionLink(employee.Id.ToString(), "Details", new { id = employee.Id }) </td> <td>@employee.Name</td> </tr> } </table>
Нам все еще нужно сделать две вещи —
-
Во-первых, нам нужно сообщить инфраструктуре MVC, что мы хотим использовать представление Layout из этого представления.
-
Во-вторых, нам нужно установить соответствующий заголовок, добавив некоторую информацию в ViewBag, как показано в приведенном выше коде.
Во-первых, нам нужно сообщить инфраструктуре MVC, что мы хотим использовать представление Layout из этого представления.
Во-вторых, нам нужно установить соответствующий заголовок, добавив некоторую информацию в ViewBag, как показано в приведенном выше коде.
Давайте сохраним все файлы и запустим приложение. Запустив приложение, вы увидите следующую домашнюю страницу.
ASP.NET Core — Razor View Start
В этой главе мы обсудим Razor View Start. Механизм представления Razor в MVC имеет соглашение, согласно которому он ищет любой файл с именем _ViewStart.cshtml и выполняет код внутри этого файла. перед выполнением кода внутри индивидуального представления.
-
Код внутри файла ViewStart не может отображаться в HTML-выводе страницы, но его можно использовать для удаления дублирующего кода из блоков кода внутри отдельных представлений.
-
В нашем примере, если мы хотим, чтобы каждое представление использовало представление Layout, созданное в предыдущей главе, мы могли бы поместить код для установки представления Layout в ViewStart вместо того, чтобы иметь код внутри каждого представления.
Код внутри файла ViewStart не может отображаться в HTML-выводе страницы, но его можно использовать для удаления дублирующего кода из блоков кода внутри отдельных представлений.
В нашем примере, если мы хотим, чтобы каждое представление использовало представление Layout, созданное в предыдущей главе, мы могли бы поместить код для установки представления Layout в ViewStart вместо того, чтобы иметь код внутри каждого представления.
пример
Давайте возьмем простой пример, чтобы увидеть, как это работает. В нашем приложении мы не хотим, чтобы каждое представление указывало, что его представление Layout является _Layout.cshtml . Поэтому щелкните правой кнопкой мыши папку «Виды» и выберите « Добавить» → «Новый элемент» .
В ASP.NET MVC есть специальный шаблон для страницы ViewStart, поэтому выберите MVC View Start Page на средней панели. Наиболее важной частью здесь является то, что этот файл называется _ViewStart.cshtml . Теперь нажмите на кнопку Добавить.
Основное использование файла ViewStart — настройка представления «Макет».
Теперь давайте перейдем к файлу Index.cshtml и обрежем строку Layout, а затем добавим ее в файл ViewStart, как показано в следующей программе.
@{ Layout = "~/Views/Shared/_Layout.cshtml"; }
-
Когда инфраструктура MVC отправляется для визуализации представления, она увидит, существует ли файл ViewStart где-нибудь в иерархии папок.
-
Мы поместили _ViewStart прямо в нашу папку Views. Это повлияет на все представления во всех папках, которые находятся в папке Views, и на представления внутри Home folder, и на Shared folder, и на любые другие папки контроллера, которые мы могли бы добавить в будущем.
-
Если мы возьмем ViewStart и поместим его только в домашнюю папку, то этот небольшой кусочек кода будет выполняться только при рендеринге одного из этих представлений в домашней папке.
-
У нас даже может быть несколько файлов ViewStart, поэтому мы можем иметь ViewStart.cshtml здесь, в папке Views, который устанавливает представление Layout для всех представлений.
-
Но если бы мы хотели изменить это значение по умолчанию для всех представлений только в папке Home, у нас мог бы быть другой ViewStart в папке Home, который устанавливает макет на что-то другое.
Когда инфраструктура MVC отправляется для визуализации представления, она увидит, существует ли файл ViewStart где-нибудь в иерархии папок.
Мы поместили _ViewStart прямо в нашу папку Views. Это повлияет на все представления во всех папках, которые находятся в папке Views, и на представления внутри Home folder, и на Shared folder, и на любые другие папки контроллера, которые мы могли бы добавить в будущем.
Если мы возьмем ViewStart и поместим его только в домашнюю папку, то этот небольшой кусочек кода будет выполняться только при рендеринге одного из этих представлений в домашней папке.
У нас даже может быть несколько файлов ViewStart, поэтому мы можем иметь ViewStart.cshtml здесь, в папке Views, который устанавливает представление Layout для всех представлений.
Но если бы мы хотели изменить это значение по умолчанию для всех представлений только в папке Home, у нас мог бы быть другой ViewStart в папке Home, который устанавливает макет на что-то другое.
Давайте сохраним все файлы и запустим приложение.
Вы увидите, что ваша домашняя страница по-прежнему отображается так же, как и раньше, и у нас все еще действует представление «Макет».
ASP.NET Core — импорт Razor View
В этой главе мы обсудим импорт Razor View. В дополнение к файлу ViewStart существует также файл ViewImports, который MVC-инфраструктура будет искать при рендеринге любого представления.
Как и файл ViewStart, мы можем поместить ViewImports.cshtml в папку, и файл ViewImports может влиять на все представления в иерархии папок.
-
Это представление является новым для данной версии MVC, в предыдущих версиях MVC мы могли использовать файл конфигурации XML для настройки определенных аспектов механизма представления Razor.
-
Эти XML-файлы исчезли, и вместо этого мы используем код.
-
Файл ViewImports — это место, где мы можем написать код и разместить общие директивы для извлечения пространств имен, которые нужны нашим представлениям.
-
Если есть пространства имен, которые мы обычно используем в наших представлениях, мы можем сделать так, чтобы директивы использования появлялись в нашем файле ViewImports один раз вместо использования директив в каждом представлении или для вывода полного пространства имен класса.
Это представление является новым для данной версии MVC, в предыдущих версиях MVC мы могли использовать файл конфигурации XML для настройки определенных аспектов механизма представления Razor.
Эти XML-файлы исчезли, и вместо этого мы используем код.
Файл ViewImports — это место, где мы можем написать код и разместить общие директивы для извлечения пространств имен, которые нужны нашим представлениям.
Если есть пространства имен, которые мы обычно используем в наших представлениях, мы можем сделать так, чтобы директивы использования появлялись в нашем файле ViewImports один раз вместо использования директив в каждом представлении или для вывода полного пространства имен класса.
пример
Давайте возьмем простой пример, чтобы увидеть, как переместить наши директивы using в ViewImports . Внутри представления Index у нас есть директива using для ввода пространства имен FirstAppDemo.Controllers, как показано в следующей программе.
@using FirstAppDemo.Controllers @model HomePageViewModel @{ ViewBag.Title = "Home"; } <h1>Welcome!</h1> <table> @foreach (var employee in Model.Employees) { <tr> <td> @Html.ActionLink(employee.Id.ToString(), "Details", new { id = employee.Id }) </td> <td>@employee.Name</td> </tr> } </table>
Использование директив позволит правильно скомпилировать код, сгенерированный из представления Razor. Без использования директив компилятор C # не сможет найти этот тип Employee. Чтобы увидеть тип сотрудника, давайте удалим директиву using из файла Index.cshtml .
@model HomePageViewModel @{ ViewBag.Title = "Home"; } <h1>Welcome!</h1> <table> @foreach (var employee in Model.Employees) { <tr> <td> @Html.ActionLink(employee.Id.ToString(), "Details", new { id = employee.Id }) </td> <td>@employee.Name</td> </tr> } </table>
Теперь запустите приложение.
Вы увидите одну из ошибок, которая гласит, что тип или пространство имен HomePageViewModel не могут быть найдены. Это может быть связано с тем, что для некоторых ваших представлений требуется одна и та же директива using . Итак, вместо того, чтобы размещать это внутри каждого представления, давайте создадим импорт View в папке Views. Это добавит использование операторов к каждому представлению, просто щелкнув правой кнопкой мыши папку «Представления» и выбрав «Добавить» → «Новый элемент».
На средней панели выберите страницу импорта представлений MVC. По умолчанию это имя _ViewImports.cshtml. Как и ViewStart, мы не можем использовать этот файл для рендеринга HTML, поэтому давайте нажмем кнопку «Добавить».
Теперь добавьте директиву using в файл _ViewImports.cshtml, как показано ниже.
@using FirstAppDemo.Controllers
Теперь все представления, которые появляются в этой папке или любой подпапке, смогут использовать типы из FirstAppDemo.Controllers без указания этого точного оператора using. Позвольте нам снова запустить ваше приложение, и вы увидите, что представление работает.
ASP.NET Core — помощники по тегам Razor
Помощники по тегам позволяют серверному коду участвовать в создании и визуализации HTML-элементов в файлах Razor. Помощники по тегам — это новая функция, похожая на помощники по HTML, которая помогает нам отображать HTML.
-
Существует много встроенных помощников тегов для общих задач, таких как создание форм, ссылок, загрузка ресурсов и т. Д. Помощники тегов созданы в C # и предназначены для элементов HTML на основе имени элемента, имени атрибута или родительского тега.
-
Например, встроенный LabelTagHelper может использовать целевой элемент HTML <label> при применении атрибутов LabelTagHelper.
-
Если вы знакомы с HTML Helpers, Tag Helpers уменьшают явные переходы между HTML и C # в представлениях Razor.
Существует много встроенных помощников тегов для общих задач, таких как создание форм, ссылок, загрузка ресурсов и т. Д. Помощники тегов созданы в C # и предназначены для элементов HTML на основе имени элемента, имени атрибута или родительского тега.
Например, встроенный LabelTagHelper может использовать целевой элемент HTML <label> при применении атрибутов LabelTagHelper.
Если вы знакомы с HTML Helpers, Tag Helpers уменьшают явные переходы между HTML и C # в представлениях Razor.
Чтобы использовать помощники тегов, нам нужно установить библиотеку NuGet, а также добавить директиву addTagHelper к представлению или представлениям, которые используют эти помощники тегов. Давайте щелкните правой кнопкой мыши по вашему проекту в обозревателе решений и выберите «Управление пакетами NuGet» ….
Найдите Microsoft.AspNet.Mvc.TagHelpers и нажмите кнопку «Установить».
Вы получите следующее диалоговое окно предварительного просмотра.
Нажмите кнопку ОК.
Нажмите кнопку Я принимаю . После установки Microsoft.AspNet.Mvc.TagHelpers перейдите в файл project.json.
{ "version": "1.0.0-*", "compilationOptions": { "emitEntryPoint": true }, "dependencies": { "Microsoft.AspNet.Mvc": "6.0.0-rc1-final", "Microsoft.AspNet.Diagnostics": "1.0.0-rc1-final", "Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final", "Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final", "Microsoft.AspNet.StaticFiles": "1.0.0-rc1-final", "EntityFramework.MicrosoftSqlServer": "7.0.0-rc1-final", "EntityFramework.Commands": "7.0.0-rc1-final", "Microsoft.AspNet.Mvc.TagHelpers": "6.0.0-rc1-final" }, "commands": { "web": "Microsoft.AspNet.Server.Kestrel", "ef": "EntityFramework.Commands" }, "frameworks": { "dnx451": { }, "dnxcore50": { } }, "exclude": [ "wwwroot", "node_modules" ], "publishExclude": [ "**.user", "**.vspscc" ] }
В разделе зависимостей вы увидите, что добавлено «Microsoft.AspNet.Mvc.TagHelpers»: «6.0.0-rc1-final» .
-
Теперь любой может создать помощника по тегам, так что если вы можете придумать нужный вам помощник по тегам, вы можете написать свой собственный помощник по тегам.
-
Вы можете поместить его прямо в свой проект приложения, но вам нужно сообщить движку представления Razor о помощнике тегов.
-
По умолчанию они не просто передаются клиенту, даже если эти помощники тегов выглядят так, как будто они вписываются в HTML.
-
Razor вызовет некоторый код для обработки помощника по тегам; он может удалить себя из HTML, а также может добавить дополнительный HTML.
-
Есть много замечательных вещей, которые вы можете сделать с помощью помощника по тегам, но вам нужно зарегистрировать свои помощники по тегам в Razor, даже в помощниках по тегам Microsoft, чтобы Razor мог обнаружить этих помощников по тегам в разметке и иметь возможность вызвать в код, который обрабатывает помощник тега.
-
Директива для этого — addTagHelper, и вы можете поместить это в отдельное представление, или, если вы планируете использовать помощники тегов во всем приложении, вы можете использовать addTagHelper внутри файла ViewImports, как показано ниже.
Теперь любой может создать помощника по тегам, так что если вы можете придумать нужный вам помощник по тегам, вы можете написать свой собственный помощник по тегам.
Вы можете поместить его прямо в свой проект приложения, но вам нужно сообщить движку представления Razor о помощнике тегов.
По умолчанию они не просто передаются клиенту, даже если эти помощники тегов выглядят так, как будто они вписываются в HTML.
Razor вызовет некоторый код для обработки помощника по тегам; он может удалить себя из HTML, а также может добавить дополнительный HTML.
Есть много замечательных вещей, которые вы можете сделать с помощью помощника по тегам, но вам нужно зарегистрировать свои помощники по тегам в Razor, даже в помощниках по тегам Microsoft, чтобы Razor мог обнаружить этих помощников по тегам в разметке и иметь возможность вызвать в код, который обрабатывает помощник тега.
Директива для этого — addTagHelper, и вы можете поместить это в отдельное представление, или, если вы планируете использовать помощники тегов во всем приложении, вы можете использовать addTagHelper внутри файла ViewImports, как показано ниже.
@using FirstAppDemo.Controllers @addTagHelper "*, Microsoft.AspNet.Mvc.TagHelpers"
Синтаксис для регистрации всех помощников тегов в сборке заключается в использовании звездочки через запятую (*,) и затем имени сборки Microsoft.AspNet.Mvc.TagHelpers . Поскольку первая часть здесь — это имя типа, здесь мы могли бы перечислить определенный помощник по тегу, если вы хотите использовать только его.
Но если вы просто хотите взять все помощники тегов, которые есть в этой сборке, вы можете просто использовать звездочку (*) . В библиотеке помощников тегов доступно множество помощников тегов. Давайте посмотрим на представление индекса.
@model HomePageViewModel @{ ViewBag.Title = "Home"; } <h1>Welcome!</h1> <table> @foreach (var employee in Model.Employees) { <tr> <td> @Html.ActionLink(employee.Id.ToString(), "Details", new { id = employee.Id }) </td> <td>@employee.Name</td> </tr> } </table>
У нас уже есть помощник HTML, использующий ActionLink для создания тега привязки, который будет указывать на URL, который позволяет нам получить сведения о сотруднике.
Давайте сначала добавим действие Details в домашний контроллер, как показано в следующей программе.
public IActionResult Details(int id) { var context = new FirstAppDemoDbContext(); SQLEmployeeData sqlData = new SQLEmployeeData(context); var model = sqlData.Get(id); if (model == null) { return RedirectToAction("Index"); } return View(model); }
Теперь нам нужно добавить представление для действия Details. Давайте создадим новый вид в папке Views → Home, назовем его Details.cshtml и добавим следующий код.
@model FirstAppDemo.Models.Employee <html xmlns = "http://www.w3.org/1999/xhtml"> <head> <title>@Model.Name</title> </head> <body> <h1>@Model.Name</h1> <div>Id: @Model.Id</div> <div> @Html.ActionLink("Home", "Index") </div> </body> </html>
Давайте теперь запустим приложение.
Когда вы щелкнете по идентификатору сотрудника, вы попадете в подробное представление.
Давайте нажмем первый идентификатор сотрудника.
Теперь, чтобы использовать помощник по тегам для этого, добавим следующую строку в файл index.cshtml и удалим помощник по HTML.
<a asp-action = "Details" asp-rout-id = "@employee.Id" >Details</a>
Asp-action = «Details» — это имя действия, к которому мы хотим добраться. Если есть какой-либо параметр, который вы хотите передать, вы можете использовать помощник тега asp-route, и здесь мы хотим включить ID в качестве параметра, чтобы мы могли использовать тег asp-route-Id taghelper.
Ниже приведена полная имплантация файла index.cshtml.
@model HomePageViewModel @{ ViewBag.Title = "Home"; } <h1>Welcome!</h1> <table> @foreach (var employee in Model.Employees) { <tr> <td> <a asp-action="Details" asp-route-id="@employee.Id" >Details</a> </td> <td>@employee.Name</td> </tr> } </table>
Позвольте нам снова запустить ваше приложение. После запуска приложения вы увидите следующую страницу.
Раньше мы отображали идентификатор в качестве текста ссылки, но теперь мы показываем текст Подробности. Теперь мы нажимаем на детали и создаем правильный URL, используя помощники тегов вместо помощников HTML.
Если вы решите использовать HTML-помощники или теги-помощники , это действительно вопрос личных предпочтений. Многие разработчики считают, что помощники по тегам легче создавать и поддерживать.
ASP.NET Core — форма редактирования бритвы
В этой главе мы продолжим обсуждение помощников по тегам. Мы также добавим новую функцию в наше приложение и дадим ему возможность редактировать данные существующего сотрудника. Мы начнем с добавления ссылки на стороне каждого сотрудника, которая перейдет к действию «Изменить» на HomeController.
@model HomePageViewModel @{ ViewBag.Title = "Home"; } <h1>Welcome!</h1> <table> @foreach (var employee in Model.Employees) { <tr> <td>@employee.Name</td> <td> <a asp-controller = "Home" asp-action = "Details" asp-routeid = "@employee.Id">Details</a> <a asp-controller = "Home" asp-action = "Edit" asp-routeid = "@employee.Id">Edit</a> </td> </tr> } </table>
У нас еще нет действия Изменить, но нам потребуется идентификатор сотрудника, который мы можем редактировать. Итак, давайте сначала создадим новый вид, щелкнув правой кнопкой мыши на папке « Виды» → «Главная » и выбрав « Добавить» → «Новые элементы» .
На средней панели выберите страницу просмотра MVC; зайдите на страницу Edit.cshtml. Теперь нажмите на кнопку Добавить.
Добавьте следующий код в файл Edit.cshtml .
@model Employee @{ ViewBag.Title = $"Edit {Model.Name}"; } <h1>Edit @Model.Name</h1> <form asp-action="Edit" method="post"> <div> <label asp-for = "Name"></label> <input asp-for = "Name" /> <span asp-validation-for = "Name"></span> </div> <div> <input type = "submit" value = "Save" /> </div> </form>
Для заголовка этой страницы мы можем сказать, что мы хотим отредактировать, а затем указать имя сотрудника.
-
Знак доллара перед правкой позволит среде выполнения заменить Model.Name значением, которое находится в этом свойстве, например, имя сотрудника.
-
Внутри тега формы мы можем использовать помощники тегов, такие как asp-action и asp-controller. так что когда пользователь отправляет эту форму, он переходит непосредственно к определенному действию контроллера.
-
В этом случае мы хотим перейти к действию Edit на том же контроллере, и мы хотим явно сказать, что для метода в этой форме он должен использовать HttpPost.
-
По умолчанию для формы используется метод GET, и мы не хотим редактировать сотрудника с помощью операции GET.
-
В теге label мы использовали помощник тега asp-for, который говорит, что это метка для свойства Name модели. Этот помощник по тегам может настроить атрибут Html.For, чтобы он имел правильное значение и задавать внутренний текст этой метки, чтобы он действительно отображал то, что мы хотим, например, имя сотрудника.
Знак доллара перед правкой позволит среде выполнения заменить Model.Name значением, которое находится в этом свойстве, например, имя сотрудника.
Внутри тега формы мы можем использовать помощники тегов, такие как asp-action и asp-controller. так что когда пользователь отправляет эту форму, он переходит непосредственно к определенному действию контроллера.
В этом случае мы хотим перейти к действию Edit на том же контроллере, и мы хотим явно сказать, что для метода в этой форме он должен использовать HttpPost.
По умолчанию для формы используется метод GET, и мы не хотим редактировать сотрудника с помощью операции GET.
В теге label мы использовали помощник тега asp-for, который говорит, что это метка для свойства Name модели. Этот помощник по тегам может настроить атрибут Html.For, чтобы он имел правильное значение и задавать внутренний текст этой метки, чтобы он действительно отображал то, что мы хотим, например, имя сотрудника.
Давайте перейдем к классу HomeController и добавим действие Edit, которое возвращает представление, которое дает пользователю форму для редактирования сотрудника, а затем нам потребуется второе действие Edit, которое будет реагировать на HttpPost, как показано ниже.
[HttpGet] public IActionResult Edit(int id) { var context = new FirstAppDemoDbContext(); SQLEmployeeData sqlData = new SQLEmployeeData(context); var model = sqlData.Get(id); if (model == null) { return RedirectToAction("Index"); } return View(model); }
Во-первых, нам нужно действие редактирования, которое будет отвечать на запрос GET. Это займет идентификатор сотрудника. Код здесь будет похож на код, который мы имеем в действии Details. Сначала мы извлечем данные сотрудника, которые пользователь хочет отредактировать. Мы также должны убедиться, что работник действительно существует. Если он не существует, мы перенаправим пользователя обратно в представление индекса. Но когда сотрудник существует, мы будем отображать представление Edit.
Мы также должны ответить на HttpPost, который отправит форма.
Давайте добавим новый класс в файл HomeController.cs, как показано в следующей программе.
public class EmployeeEditViewModel { [Required, MaxLength(80)] public string Name { get; set; } }
В действии Edit, которое ответит на HttpPost, примет EmployeeEditViewModel, но не самого сотрудника, потому что мы хотим захватывать только те элементы, которые находятся в форме в файле Edit.cshtml.
Ниже приведена реализация действия Edit.
[HttpPost] public IActionResult Edit(int id, EmployeeEditViewModel input) { var context = new FirstAppDemoDbContext(); SQLEmployeeData sqlData = new SQLEmployeeData(context); var employee = sqlData.Get(id); if (employee != null && ModelState.IsValid) { employee.Name = input.Name; context.SaveChanges(); return RedirectToAction("Details", new { id = employee.Id }); } return View(employee); }
Форма редактирования всегда должна доставляться с URL, который имеет идентификатор в URL в соответствии с нашими правилами маршрутизации, например, / home / edit / 1 .
-
Форма всегда будет публиковаться по тому же URL, / home / edit / 1.
-
Инфраструктура MVC сможет извлечь этот идентификатор из URL и передать его в качестве параметра.
-
Нам всегда нужно проверять, является ли ModelState допустимым, а также убедиться, что этот сотрудник находится в базе данных, и он не является нулевым, прежде чем мы выполним операцию обновления в базе данных.
-
Если ничего из этого не соответствует действительности, мы вернем представление и позволим пользователю повторить попытку. Хотя в реальном приложении с одновременными пользователями, если сотрудник является нулевым, это может быть связано с тем, что кто-то удалил данные сотрудника.
-
Если этот сотрудник не существует, скажите пользователю, что сотрудник не существует.
-
В противном случае проверьте ModelState. Если ModelState недействителен, тогда верните представление. Это позволяет исправить редактирование и сделать ModelState допустимым.
-
Скопируйте имя из модели представления ввода для сотрудника, полученного из базы данных, и сохраните изменения. Метод SaveChagnes () будет сбрасывать все эти изменения в базу данных.
Форма всегда будет публиковаться по тому же URL, / home / edit / 1.
Инфраструктура MVC сможет извлечь этот идентификатор из URL и передать его в качестве параметра.
Нам всегда нужно проверять, является ли ModelState допустимым, а также убедиться, что этот сотрудник находится в базе данных, и он не является нулевым, прежде чем мы выполним операцию обновления в базе данных.
Если ничего из этого не соответствует действительности, мы вернем представление и позволим пользователю повторить попытку. Хотя в реальном приложении с одновременными пользователями, если сотрудник является нулевым, это может быть связано с тем, что кто-то удалил данные сотрудника.
Если этот сотрудник не существует, скажите пользователю, что сотрудник не существует.
В противном случае проверьте ModelState. Если ModelState недействителен, тогда верните представление. Это позволяет исправить редактирование и сделать ModelState допустимым.
Скопируйте имя из модели представления ввода для сотрудника, полученного из базы данных, и сохраните изменения. Метод SaveChagnes () будет сбрасывать все эти изменения в базу данных.
Ниже приведена полная реализация HomeController.
using Microsoft.AspNet.Mvc; using FirstAppDemo.ViewModels; using FirstAppDemo.Services; using FirstAppDemo.Entities; using FirstAppDemo.Models; using System.Collections.Generic; using System.Linq; using System.ComponentModel.DataAnnotations; namespace FirstAppDemo.Controllers { public class HomeController : Controller { public ViewResult Index() { var model = new HomePageViewModel(); using (var context = new FirstAppDemoDbContext()) { SQLEmployeeData sqlData = new SQLEmployeeData(context); model.Employees = sqlData.GetAll(); } return View(model); } public IActionResult Details(int id) { var context = new FirstAppDemoDbContext(); SQLEmployeeData sqlData = new SQLEmployeeData(context); var model = sqlData.Get(id) if (model == null) { return RedirectToAction("Index"); } return View(model); } [HttpGet] public IActionResult Edit(int id) { var context = new FirstAppDemoDbContext(); SQLEmployeeData sqlData = new SQLEmployeeData(context); var model = sqlData.Get(id); if (model == null) { return RedirectToAction("Index"); } return View(model); } [HttpPost] public IActionResult Edit(int id, EmployeeEditViewModel input) { var context = new FirstAppDemoDbContext(); SQLEmployeeData sqlData = new SQLEmployeeData(context); var employee = sqlData.Get(id); if (employee != null && ModelState.IsValid) { employee.Name = input.Name; context.SaveChanges(); return RedirectToAction("Details", new { id = employee.Id }); } return View(employee); } } public class SQLEmployeeData { private FirstAppDemoDbContext _context { get; set; } public SQLEmployeeData(FirstAppDemoDbContext context) { _context = context; } public void Add(Employee emp) { _context.Add(emp); _context.SaveChanges(); } public Employee Get(int ID) { return _context.Employees.FirstOrDefault(e => e.Id == ID); } public IEnumerable<Employee> GetAll() { return _context.Employees.ToList<Employee>(); } } public class HomePageViewModel { public IEnumerable<Employee> Employees { get; set; } } public class EmployeeEditViewModel { [Required, MaxLength(80)] public string Name { get; set; } } }
Давайте скомпилируем программу и запустим приложение.
Теперь у нас есть ссылка «Изменить»; давайте отредактируем детали Джоша, нажав на ссылку Изменить.
Давайте изменим имя на Джош Гробан.
Нажмите кнопку Сохранить.
Вы можете видеть, что имя было изменено на Джоша Гробана, как на скриншоте выше. Теперь давайте перейдем по ссылке Home.
На домашней странице вы увидите обновленное имя.
ASP.NET Core — Обзор личных данных
В этой главе мы кратко обсудим платформу ASP.NET Core Identity. ASP.NET Core Identity Framework используется для реализации проверки подлинности форм. Существует множество вариантов идентификации пользователей, включая проверку подлинности Windows и всех сторонних поставщиков удостоверений, таких как Google, Microsoft, Facebook, GitHub и т. Д.
-
Платформа Identity — это еще одна зависимость, которую мы добавим к нашему приложению в файле project.js.
-
Эта структура позволяет нам добавлять функции, где пользователи могут зарегистрироваться и войти в систему с локальным паролем.
-
Платформа также поддерживает двухфакторную аутентификацию, сторонние поставщики удостоверений и другие функции.
-
Мы собираемся сосредоточиться на сценариях, где пользователь может зарегистрироваться и войти и выйти.
Платформа Identity — это еще одна зависимость, которую мы добавим к нашему приложению в файле project.js.
Эта структура позволяет нам добавлять функции, где пользователи могут зарегистрироваться и войти в систему с локальным паролем.
Платформа также поддерживает двухфакторную аутентификацию, сторонние поставщики удостоверений и другие функции.
Мы собираемся сосредоточиться на сценариях, где пользователь может зарегистрироваться и войти и выйти.
Для этого нам нужно создать сущность User, и этот класс будет наследоваться от базового класса в платформе Identity, а базовый класс предоставляет нам наши стандартные пользовательские свойства, такие как имя пользователя и адрес электронной почты.
-
Мы можем включить в этот класс столько дополнительных свойств, сколько мы хотим, чтобы хранить информацию о наших пользователях.
-
Нам нужно взять этот класс User и подключить его к классу UserStore, предоставленному каркасом Identity.
-
UserStore — это класс, с которым наш код будет общаться, чтобы создавать пользователей и проверять пароли пользователей.
-
В конечном счете, UserStore будет общаться с базой данных. Платформа Identity поддерживает Entity Framework и все базы данных, которые могут работать с Entity Framework.
-
Но вы можете реализовать свой собственный UserStore для работы с любым источником данных.
-
Для правильной работы с Entity Framework наш класс User также подключится к классу IdentityDb.
-
Это класс, который использует Entity Framework DBContext для фактической работы с базой данных.
-
Нам нужно будет включить этот IdentityDb в наше приложение, чтобы существующий класс DataContext наследовал от IdentityDb вместо DBContext Entity Framework.
-
Это IdentityDb и UserStore, которые работают вместе для хранения информации о пользователях и проверки паролей пользователей, хешированных паролей, находящихся в базе данных.
Мы можем включить в этот класс столько дополнительных свойств, сколько мы хотим, чтобы хранить информацию о наших пользователях.
Нам нужно взять этот класс User и подключить его к классу UserStore, предоставленному каркасом Identity.
UserStore — это класс, с которым наш код будет общаться, чтобы создавать пользователей и проверять пароли пользователей.
В конечном счете, UserStore будет общаться с базой данных. Платформа Identity поддерживает Entity Framework и все базы данных, которые могут работать с Entity Framework.
Но вы можете реализовать свой собственный UserStore для работы с любым источником данных.
Для правильной работы с Entity Framework наш класс User также подключится к классу IdentityDb.
Это класс, который использует Entity Framework DBContext для фактической работы с базой данных.
Нам нужно будет включить этот IdentityDb в наше приложение, чтобы существующий класс DataContext наследовал от IdentityDb вместо DBContext Entity Framework.
Это IdentityDb и UserStore, которые работают вместе для хранения информации о пользователях и проверки паролей пользователей, хешированных паролей, находящихся в базе данных.
Есть две части ASP.NET Core Identity Framework, которые нам нужно знать
SignInManager
Это одна из двух частей Identity Framework —
-
Как видно из названия, SignInManager может войти в систему после того, как мы подтвердим пароль.
-
Мы также можем использовать этот менеджер для выхода из системы.
-
При проверке подлинности с помощью форм вход и выход осуществляются путем управления файлом cookie.
-
Когда мы сообщаем SignInManager о входе пользователя в систему, менеджер отправляет файл cookie в браузер пользователя, и браузер отправляет этот файл cookie при каждом последующем запросе. Это помогает нам идентифицировать этого пользователя.
Как видно из названия, SignInManager может войти в систему после того, как мы подтвердим пароль.
Мы также можем использовать этот менеджер для выхода из системы.
При проверке подлинности с помощью форм вход и выход осуществляются путем управления файлом cookie.
Когда мы сообщаем SignInManager о входе пользователя в систему, менеджер отправляет файл cookie в браузер пользователя, и браузер отправляет этот файл cookie при каждом последующем запросе. Это помогает нам идентифицировать этого пользователя.
Identity Middleware
Это второй кусок основы —
-
Чтение файла cookie, отправленного SignInManager, и идентификация пользователя, это происходит в последнем фрагменте платформы, Identity Middleware.
-
Нам нужно будет сконфигурировать это промежуточное ПО в конвейер нашего приложения для обработки cookie, установленного SignInManager. Мы также увидим некоторые другие особенности этого промежуточного программного обеспечения в следующих нескольких главах.
Чтение файла cookie, отправленного SignInManager, и идентификация пользователя, это происходит в последнем фрагменте платформы, Identity Middleware.
Нам нужно будет сконфигурировать это промежуточное ПО в конвейер нашего приложения для обработки cookie, установленного SignInManager. Мы также увидим некоторые другие особенности этого промежуточного программного обеспечения в следующих нескольких главах.
ASP.NET Core — атрибут авторизации
В этой главе мы обсудим атрибут авторизации. До сих пор в нашем приложении мы позволяли анонимным пользователям делать что угодно. Они могут редактировать данные о сотрудниках и просматривать их, но у нас нет возможности создать нового сотрудника. Давайте сначала добавим функцию создания, а затем мы ограничим доступ пользователя с помощью атрибута Authorize.
Нам нужно начать с создания новой страницы MVC View внутри Views → Home folder и вызвать ее Create.cshtml, а затем добавить следующий код.
@model Employee @{ ViewBag.Title = "Create"; } <h1>Create</h1> @using (Html.BeginForm()) { <div> @Html.LabelFor(m => m.Name) @Html.EditorFor(m => m.Name) @Html.ValidationMessageFor(m => m.Name) </div> <div> <input type = "submit" value = "Save" /> </div> }
Теперь мы добавим метод действия в HomeController для POST и GET, как показано в следующей программе.
[HttpGet] public ViewResult Create() { return View(); } [HttpPost] public IActionResult Create(EmployeeEditViewModel model) { if (ModelState.IsValid) { var employee = new Employee(); employee.Name = model.Name; var context = new FirstAppDemoDbContext(); SQLEmployeeData sqlData = new SQLEmployeeData(context); sqlData.Add(employee); return RedirectToAction("Details", new { id = employee.Id }); } return View(); }
Давайте добавим ссылку на Create View в файле Index.cshtml, как показано в следующей программе.
@model HomePageViewModel @{ ViewBag.Title = "Home"; } <h1>Welcome!</h1> <table> @foreach (var employee in Model.Employees) { <tr> <td>@employee.Name <td> <a asp-controller = "Home" asp-action = "Details" asp-routeid = "@employee.Id">Details</a> <a asp-controller = "Home" asp-action = "Edit" asp-routeid = "@employee.Id">Edit</a> </td> </tr> } </table> <div> <a asp-action = "Create">Create</a> </div>
Запустите приложение; Вы увидите следующую страницу.
На главной странице вы увидите ссылку Создать. Когда вы нажмете ссылку «Создать», откроется окно «Создать представление».
Введите имя в поле «Имя» и нажмите кнопку «Сохранить».
Теперь вы увидите подробный вид недавно добавленного сотрудника. Давайте перейдем по ссылке Домой.
В этом приложении каждый пользователь может создавать, редактировать сотрудника, и каждый может видеть подробный вид. Мы хотим изменить это поведение, чтобы в будущем анонимные пользователи могли видеть только список сотрудников на домашней странице, но любое другое действие требует, чтобы пользователь идентифицировал себя и выполнил вход. Мы можем сделать это с помощью атрибута Authorize .
Вы можете разместить атрибут Authorize на контроллере или на отдельных действиях внутри контроллера.
[Authorize] public class HomeController : Controller { //.... }
-
Когда мы размещаем атрибут Authorize на самом контроллере, атрибут authorize применяется ко всем внутренним действиям.
-
Инфраструктура MVC не позволит запросу выполнить действие, защищенное этим атрибутом, если пользователь не пройдет проверку авторизации.
-
По умолчанию, если вы не используете никаких других параметров, единственная проверка, которую сделает атрибут Authorize, — это проверка, чтобы убедиться, что пользователь вошел в систему, чтобы мы знали его личность.
-
Но вы можете использовать параметры, чтобы указать любую необычную политику авторизации, которая вам нравится.
-
Существует также атрибут AllowAnonymous . Этот атрибут полезен, когда вы хотите использовать атрибут Authorize на контроллере для защиты всех действий внутри него, но есть одно действие или одно или два действия, которые вы хотите снять защиту и разрешить анонимным пользователям выполнять это конкретное действие.
Когда мы размещаем атрибут Authorize на самом контроллере, атрибут authorize применяется ко всем внутренним действиям.
Инфраструктура MVC не позволит запросу выполнить действие, защищенное этим атрибутом, если пользователь не пройдет проверку авторизации.
По умолчанию, если вы не используете никаких других параметров, единственная проверка, которую сделает атрибут Authorize, — это проверка, чтобы убедиться, что пользователь вошел в систему, чтобы мы знали его личность.
Но вы можете использовать параметры, чтобы указать любую необычную политику авторизации, которая вам нравится.
Существует также атрибут AllowAnonymous . Этот атрибут полезен, когда вы хотите использовать атрибут Authorize на контроллере для защиты всех действий внутри него, но есть одно действие или одно или два действия, которые вы хотите снять защиту и разрешить анонимным пользователям выполнять это конкретное действие.
[AllowAnonymous] public ViewResult Index() { var model = new HomePageViewModel(); using (var context = new FirstAppDemoDbContext()) { SQLEmployeeData sqlData = new SQLEmployeeData(context); model.Employees = sqlData.GetAll(); } return View(model); }
Давайте попробуем эти атрибуты в нашем приложении. В запущенном приложении анонимный пользователь может редактировать сотрудника.
Мы хотим изменить это и заставить пользователей войти в систему и идентифицировать себя, прежде чем они смогут редактировать сотрудника. Давайте теперь перейдем к HomeController. Мы ограничим доступ к одному или двум действиям здесь. Мы всегда можем поместить атрибут Authorize в те конкретные действия, которые мы хотим защитить. Мы также можем разместить атрибут Authorize на самом контроллере, а этот атрибут Authorize находится в пространстве имен Microsoft.AspNet.Authorization.
Теперь мы будем использовать атрибут Authorize и заставлять пользователей идентифицировать себя, чтобы войти в этот контроллер, за исключением домашней страницы, как показано в следующей программе.
[Authorize] public class HomeController : Controller { [AllowAnonymous] public ViewResult Index() { var model = new HomePageViewModel(); using (var context = new FirstAppDemoDbContext()) { SQLEmployeeData sqlData = new SQLEmployeeData(context); model.Employees = sqlData.GetAll(); } return View(model); } public IActionResult Details(int id) { var context = new FirstAppDemoDbContext(); SQLEmployeeData sqlData = new SQLEmployeeData(context); var model = sqlData.Get(id); if (model == null) { return RedirectToAction("Index"); } return View(model); } [HttpGet] public IActionResult Edit(int id) { var context = new FirstAppDemoDbContext(); SQLEmployeeData sqlData = new SQLEmployeeData(context); var model = sqlData.Get(id); if (model == null) { return RedirectToAction("Index"); } return View(model); } [HttpPost] public IActionResult Edit(int id, EmployeeEditViewModel input) { var context = new FirstAppDemoDbContext(); SQLEmployeeData sqlData = new SQLEmployeeData(context); var employee = sqlData.Get(id); if (employee != null && ModelState.IsValid) { employee.Name = input.Name; context.SaveChanges(); return RedirectToAction("Details", new { id = employee.Id }); } return View(employee); } [HttpGet] public ViewResult Create() { return View(); } [HttpPost] public IActionResult Create(EmployeeEditViewModel model) { if (ModelState.IsValid) { var employee = new Employee(); employee.Name = model.Name; var context = new FirstAppDemoDbContext(); SQLEmployeeData sqlData = new SQLEmployeeData(context); sqlData.Add(employee); return RedirectToAction("Details", new { id = employee.Id }); } return View(); } }
Домашняя страница или файл Index.cshtml, в котором отображается список сотрудников, имеют атрибут AllowAnonymous . Давайте теперь запустим ваше приложение.
Нажмите клавишу F12, чтобы открыть инструменты разработчика . Теперь перейдите на вкладку Сеть .
Есть несколько вещей, которые мы хотим наблюдать в инструментах разработчика, чтобы мы могли видеть, как все работает. При нажатии на ссылку «Изменить» вы увидите пустую страницу.
Если вы посмотрите на инструменты разработчика, то увидите, что код состояния HTTP, который был возвращен с сервера, представлял собой код состояния 401 .
Код состояния 401 сообщает браузеру, что запрос не был пропущен из-за отсутствия действительных учетных данных аутентификации. Это говорит нам о том, что атрибут Authorize работает.
Аналогично, когда вы нажимаете ссылку «Создать» на домашней странице, вы видите ту же ошибку, что и на следующем снимке экрана.
-
Здесь плохая часть заключается в том, что пользователь остается на пустой странице и, если у него не открыты инструменты разработчика, они могут не знать, что это была проблема аутентификации.
-
Вот где может помочь Identity Framework и помочь.
-
Инфраструктура Identity может определять, когда часть приложения хочет вернуть код состояния 401, поскольку пользователю не разрешено туда заходить, и инфраструктура Identity может превратить это в страницу входа в систему и позволить пользователю обойти эту проблему.
-
Мы увидим, как это работает, как только мы установим и настроим платформу Identity.
-
Но сейчас мы видим, что атрибут Authorize работает.
Здесь плохая часть заключается в том, что пользователь остается на пустой странице и, если у него не открыты инструменты разработчика, они могут не знать, что это была проблема аутентификации.
Вот где может помочь Identity Framework и помочь.
Инфраструктура Identity может определять, когда часть приложения хочет вернуть код состояния 401, поскольку пользователю не разрешено туда заходить, и инфраструктура Identity может превратить это в страницу входа в систему и позволить пользователю обойти эту проблему.
Мы увидим, как это работает, как только мы установим и настроим платформу Identity.
Но сейчас мы видим, что атрибут Authorize работает.
ASP.NET Core — Конфигурация идентичности
В этой главе мы установим и настроим инфраструктуру Identity, что займет немного времени. Если вы зайдете в Visual Studio и создадите новое приложение ASP.NET Core и выберете полный шаблон веб-приложения с аутентификацией, настроенной для отдельных учетных записей пользователей, этот новый проект будет включать все биты инфраструктуры Identity, настроенной для вас.
Мы начали с пустого проекта. Теперь мы настроим платформу Identity с нуля, что является хорошим способом узнать обо всех компонентах полного шаблона приложения, потому что это может сбить с толку, если вы не проработали подробно все коды.
Для начала нам нужно установить зависимость Microsoft.AspNet.Identity . Мы продолжим, установив Microsoft.AspNet.Identity.EntityFramework и затем внедрив платформу Identity, которая работает с Entity Framework.
-
Если мы возьмем зависимость от Identity.EntityFramework, пакет будет включать пакет Identity.
-
Если вы создаете свои собственные хранилища данных, вы можете работать только с пакетом Identity.
-
После того, как наши зависимости установлены, мы можем создать пользовательский класс User со всей информацией, которую мы хотим сохранить о пользователе.
-
Для этого приложения мы собираемся наследовать от класса, предоставляемого платформой Identity, и этот класс предоставит нам все необходимое, например, свойство Username и место для хранения хешированных паролей.
Если мы возьмем зависимость от Identity.EntityFramework, пакет будет включать пакет Identity.
Если вы создаете свои собственные хранилища данных, вы можете работать только с пакетом Identity.
После того, как наши зависимости установлены, мы можем создать пользовательский класс User со всей информацией, которую мы хотим сохранить о пользователе.
Для этого приложения мы собираемся наследовать от класса, предоставляемого платформой Identity, и этот класс предоставит нам все необходимое, например, свойство Username и место для хранения хешированных паролей.
-
Нам также потребуется изменить наш класс FirstAppDemoDbContext, чтобы он наследовал от класса IdentityDb инфраструктуры Identity .
-
IdentityDb дает нам все, что нам нужно хранить как пользовательскую информацию в Entity Framework. После того, как у нас есть класс User и DBContext , нам нужно будет настроить службы Identity в приложении с помощью метода ConfigureServices класса Startup.
-
Точно так же, как когда нам нужно было добавить сервисы для поддержки инфраструктуры MVC, каркасу Identity нужны сервисы, добавленные в приложение для работы.
-
Эти службы включают в себя такие службы, как служба UserStore и SignInManager .
-
Мы будем внедрять эти сервисы в наш контроллер для создания пользователей и выдачи файлов cookie в соответствующее время.
-
Наконец, во время запуска метода Configure нам потребуется добавить промежуточное программное обеспечение Identity.
-
Это промежуточное программное обеспечение не только поможет превратить файлы cookie в личность пользователя, но также гарантирует, что пользователь не увидит пустую страницу с ответом 401.
Нам также потребуется изменить наш класс FirstAppDemoDbContext, чтобы он наследовал от класса IdentityDb инфраструктуры Identity .
IdentityDb дает нам все, что нам нужно хранить как пользовательскую информацию в Entity Framework. После того, как у нас есть класс User и DBContext , нам нужно будет настроить службы Identity в приложении с помощью метода ConfigureServices класса Startup.
Точно так же, как когда нам нужно было добавить сервисы для поддержки инфраструктуры MVC, каркасу Identity нужны сервисы, добавленные в приложение для работы.
Эти службы включают в себя такие службы, как служба UserStore и SignInManager .
Мы будем внедрять эти сервисы в наш контроллер для создания пользователей и выдачи файлов cookie в соответствующее время.
Наконец, во время запуска метода Configure нам потребуется добавить промежуточное программное обеспечение Identity.
Это промежуточное программное обеспечение не только поможет превратить файлы cookie в личность пользователя, но также гарантирует, что пользователь не увидит пустую страницу с ответом 401.
Давайте теперь следуем инструкциям ниже.
Шаг 1 — Нам нужно продолжить, добавив зависимость от платформы Identity. Давайте добавим зависимость Microsoft.AspNet.Identity.EntityFramework в файл project.json. Это будет включать в себя все другие необходимые пакеты удостоверений, которые нам нужны.
{ "version": "1.0.0-*", "compilationOptions": { "emitEntryPoint": true }, "dependencies": { "Microsoft.AspNet.Mvc": "6.0.0-rc1-final", "Microsoft.AspNet.Diagnostics": "1.0.0-rc1-final", "Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final", "Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final", "Microsoft.AspNet.StaticFiles": "1.0.0-rc1-final", "EntityFramework.MicrosoftSqlServer": "7.0.0-rc1-final", "EntityFramework.Commands": "7.0.0-rc1-final", "Microsoft.AspNet.Mvc.TagHelpers": "6.0.0-rc1-final", "Microsoft.AspNet.Identity.EntityFramework": "3.0.0-rc1-final" }, "commands": { "web": "Microsoft.AspNet.Server.Kestrel", "ef": "EntityFramework.Commands" }, "frameworks": { "dnx451": { }, "dnxcore50": { } }, "exclude": [ "wwwroot", "node_modules" ], "publishExclude": [ "**.user", "**.vspscc" ] }
Шаг 2 — Сохраните этот файл. Visual Studio восстанавливает пакеты, и теперь мы можем добавить наш класс User. Давайте добавим класс User, щелкнув правой кнопкой мыши на папке Models и выбрав Add → Class.
Назовите этого пользователя класса и нажмите кнопку Добавить, как на скриншоте выше. В этом классе вы можете добавить свойства для хранения любой информации о пользователе, которую вы хотите сохранить.
Шаг 3 — Давайте выведем класс User из класса, предоставленного платформой Identity. Это класс IdentityUser, который находится в пространстве имен Identity.EntityFramework.
using Microsoft.AspNet.Identity.EntityFramework; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace FirstAppDemo.Models { public class User : IdentityUser { } }
Шаг 4 — Теперь давайте перейдем к IdentityUser, поместим курсор на этот символ и нажмите F12, чтобы увидеть представление метаданных Visual Studio.
#region Assembly Microsoft.AspNet.Identity.EntityFramework, Version = 3.0.0.0, namespace Microsoft.AspNet.Identity.EntityFramework { public class IdentityUser : IdentityUser<string> { public IdentityUser(); public IdentityUser(string userName); } }
Шаг 5. Вы можете видеть, что IdentityUser является производным от IdentityUser строки. Вы можете изменить тип первичного ключа, унаследовав его от IdentityUser и указав наш параметр универсального типа. Вы также можете хранить вещи с первичным ключом, который в идеале является целочисленным значением.
Шаг 6 — Давайте теперь поместим курсор на IdentityUser строки и снова нажмите F12, чтобы перейти к представлению метаданных.
Теперь вы можете видеть всю информацию, связанную с пользователем по умолчанию. Информация включает в себя следующее —
-
Поля, которые мы не будем использовать в этом приложении, но доступны для использования.
-
Платформа Identity может отслеживать количество неудачных попыток входа в систему для конкретного пользователя и может блокировать эту учетную запись в течение определенного периода времени.
-
Поля для хранения PasswordHash, PhoneNumber. Мы будем использовать два важных поля — PasswordHash и UserName.
-
Мы также будем неявно использовать первичный ключ и свойство ID пользователя. Вы также можете использовать это свойство, если вам нужно выполнить запрос для конкретного пользователя.
Поля, которые мы не будем использовать в этом приложении, но доступны для использования.
Платформа Identity может отслеживать количество неудачных попыток входа в систему для конкретного пользователя и может блокировать эту учетную запись в течение определенного периода времени.
Поля для хранения PasswordHash, PhoneNumber. Мы будем использовать два важных поля — PasswordHash и UserName.
Мы также будем неявно использовать первичный ключ и свойство ID пользователя. Вы также можете использовать это свойство, если вам нужно выполнить запрос для конкретного пользователя.
Шаг 7 — Теперь нам нужно убедиться, что пользователь включен в наш DBContext. Итак, давайте откроем FirstAppDemoDBContext, который есть в нашем приложении, и вместо того, чтобы выводить его напрямую из DBContext, который является встроенным базовым классом Entity Framework, нам теперь нужно извлечь его из IdentityDbContext.
using Microsoft.AspNet.Identity.EntityFramework; using Microsoft.Data.Entity; namespace FirstAppDemo.Models { public class FirstAppDemoDbContext : IdentityDbContext<User> { public DbSet<Employee> Employees { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlServer("Data Source = (localdb)\\MSSQLLocalDB; Initial Catalog = FirstAppDemo;Integrated Security = True; Connect Timeout = 30;Encrypt = False;TrustServerCertificate = True; ApplicationIntent = ReadWrite;MultiSubnetFailover = False"); } } }
Шаг 8 — Класс IdentityDbContext также находится в пространстве имен Microsoft.AspNet.Identity.EntityFramework, и мы можем указать тип пользователя, который он должен хранить. Таким образом, любые дополнительные поля, которые мы добавляем в класс User, попадают в базу данных.
-
IdentityDbContext предоставляет дополнительные наборы данных DbSets не только для хранения пользователя, но и для информации о пользовательских ролях и заявках пользователей.
-
Наш пользовательский класс готов сейчас. Наш класс FirstAppDemoDbContext настроен для работы со структурой Identity.
-
Теперь мы можем перейти к Configure и ConfigureServices, чтобы настроить Identity Framework.
IdentityDbContext предоставляет дополнительные наборы данных DbSets не только для хранения пользователя, но и для информации о пользовательских ролях и заявках пользователей.
Наш пользовательский класс готов сейчас. Наш класс FirstAppDemoDbContext настроен для работы со структурой Identity.
Теперь мы можем перейти к Configure и ConfigureServices, чтобы настроить Identity Framework.
Шаг 9 — Давайте начнем с ConfigureServices . В дополнение к нашим службам MVC и службам Entity Framework нам необходимо добавить наши службы идентификации. Это добавит все сервисы, на которые опирается платформа Identity для выполнения своей работы.
public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddEntityFramework() .AddSqlServer() .AddDbContext<FirstAppDemoDbContext> (option => option.UseSqlServer(Configuration["database:connection"])); services.AddIdentity<User, IdentityRole>() .AddEntityFrameworkStores<FirstAppDemoDbContext>(); }
-
Метод AddIdentity принимает два параметра общего типа — тип объекта пользователя и тип объекта роли.
-
Два параметра универсального типа — это типы нашего пользователя — класс User, который мы только что создали, и класс Role, с которым мы хотим работать. Теперь мы будем использовать встроенную IdentityRole. Этот класс находится в пространстве имен EntityFramework.
-
Когда мы используем Entity Framework с Identity, нам также необходимо вызвать второй метод — AddEntityFrameworkStores.
-
Метод AddEntityFrameworkStores настроит такие службы, как UserStore, служба, используемая для создания пользователей и проверки их паролей.
Метод AddIdentity принимает два параметра общего типа — тип объекта пользователя и тип объекта роли.
Два параметра универсального типа — это типы нашего пользователя — класс User, который мы только что создали, и класс Role, с которым мы хотим работать. Теперь мы будем использовать встроенную IdentityRole. Этот класс находится в пространстве имен EntityFramework.
Когда мы используем Entity Framework с Identity, нам также необходимо вызвать второй метод — AddEntityFrameworkStores.
Метод AddEntityFrameworkStores настроит такие службы, как UserStore, служба, используемая для создания пользователей и проверки их паролей.
Шаг 10. Следующие две строки — все, что нам нужно для настройки служб для приложения.
services.AddIdentity<User, IdentityRole>() .AddEntityFrameworkStores<FirstAppDemoDbContext>();
Шаг 11 — Нам также нужно добавить промежуточное программное обеспечение. Расположение того, куда мы вставляем промежуточное ПО, важно, потому что, если мы вставим промежуточное ПО слишком поздно в конвейер, у него никогда не будет возможности обработать запрос.
И если нам требуются проверки авторизации внутри наших контроллеров MVC, нам нужно вставить промежуточное ПО Identity перед платформой MVC, чтобы убедиться, что файлы cookie, а также ошибки 401 успешно обрабатываются.
public void Configure(IApplicationBuilder app) { app.UseIISPlatformHandler(); app.UseDeveloperExceptionPage(); app.UseRuntimeInfoPage(); app.UseFileServer(); app.UseIdentity(); app.UseMvc(ConfigureRoute); app.Run(async (context) => { var msg = Configuration["message"]; await context.Response.WriteAsync(msg); }); }
Шаг 12. В то место, куда мы вставляем промежуточное ПО, мы добавляем промежуточное ПО Identity. Ниже приведена полная реализация файла Startup.cs.
using Microsoft.AspNet.Builder; using Microsoft.AspNet.Hosting; using Microsoft.AspNet.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Configuration; using FirstAppDemo.Services; using Microsoft.AspNet.Routing; using System; using FirstAppDemo.Entities; using Microsoft.Data.Entity; using FirstAppDemo.Models; using Microsoft.AspNet.Identity.EntityFramework; namespace FirstAppDemo { public class Startup { public Startup() { var builder = new ConfigurationBuilder() .AddJsonFile("AppSettings.json"); Configuration = builder.Build(); } public IConfiguration Configuration { get; set; } // This method gets called by the runtime. // Use this method to add services to the container. // For more information on how to configure your application, // visit http://go.microsoft.com/fwlink/?LinkID = 398940 public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddEntityFramework() .AddSqlServer() .AddDbContext<FirstAppDemoDbContext>(option => option.UseSqlServer(Configuration["database:connection"])); services.AddIdentity<User, IdentityRole>() .AddEntityFrameworkStores<FirstAppDemoDbContext>(); } // This method gets called by the runtime. // Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app) { app.UseIISPlatformHandler(); app.UseDeveloperExceptionPage(); app.UseRuntimeInfoPage(); app.UseFileServer(); app.UseIdentity(); app.UseMvc(ConfigureRoute); app.Run(async (context) => { var msg = Configuration["message"]; await context.Response.WriteAsync(msg); }); } private void ConfigureRoute(IRouteBuilder routeBuilder) { //Home/Index routeBuilder.MapRoute("Default", "{controller=Home}/{action=Index}/{id?}"); } // Entry point for the application. public static void Main(string[] args) => WebApplication.Run<Startup>(args); } }
Шаг 13 — Давайте теперь двигаться вперед, создав приложение. В следующей главе нам нужно добавить еще одну миграцию Entity Framework, чтобы убедиться, что у нас есть схема Identity в нашей базе данных SQL Server.
ASP.NET Core — миграция удостоверений
В этой главе мы обсудим миграцию удостоверений. В ASP.NET Core MVC функции аутентификации и идентификации настраиваются в файле Startup.cs.
public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddEntityFramework() .AddSqlServer() .AddDbContext<FirstAppDemoDbContext>option. UseSqlServer(Configuration["database:connection"])); services.AddIdentity<User, IdentityRole>() .AddEntityFrameworkStores<FirstAppDemoDbContext>(); }
Каждый раз, когда вы вносите изменения в один из ваших классов сущностей или вносите изменения в свой производный класс DBContext, скорее всего, вам придется создать новый сценарий миграции, который будет применяться к базе данных и синхронизировать схему с тем, что находится в вашем коде. ,
Это имеет место в нашем приложении, потому что теперь мы извлекаем наш класс FirstAppDemoDbContext из класса IdentityDbContext, и он содержит свои собственные наборы DbSets, и он также создаст схему для хранения всей информации об объектах, которыми он управляет.
using Microsoft.AspNet.Identity.EntityFramework; using Microsoft.Data.Entity; namespace FirstAppDemo.Models { public class FirstAppDemoDbContext : IdentityDbContext<User> { public DbSet<Employee> Employees { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlServer("Data Source = (localdb)\\MSSQLLocalDB; Initial Catalog = FirstAppDemo;Integrated Security = True; Connect Timeout = 30;Encrypt = False; TrustServerCertificate = True;ApplicationIntent = ReadWrite; MultiSubnetFailover = False"); } } }
Давайте теперь откроем командную строку и убедимся, что мы находимся в том месте, где существует файл project.json для нашего проекта.
Мы также можем получить команды Entity Framework, набрав dnx ef .
В нашем файле project.json есть раздел, который сопоставляет это ключевое слово «ef» с EntityFramework.Commands.
"commands": { "web": "Microsoft.AspNet.Server.Kestrel", "ef": "EntityFramework.Commands" }
Мы можем добавить миграцию отсюда. Нам также необходимо указать имя для миграции. Давайте использовать v2 для версии 2 и нажать Enter.
Когда миграция будет завершена, у вас будет файл v2 в папке миграции.
Теперь мы хотим применить эту миграцию к нашей базе данных, выполнив команду «dnx ef database update» .
Entity Framework увидит, что существует миграция, которую необходимо применить, и выполнит эту миграцию.
Если вы зайдете в Обозреватель объектов SQL Server, вы увидите таблицу Employee, которую мы создали ранее. Вы также увидите несколько дополнительных таблиц, в которых должны храниться пользователи, утверждения, роли и некоторые таблицы сопоставления, которые сопоставляют пользователей с конкретными ролями.
Все эти таблицы связаны с сущностями, которые предоставляет структура Identity.
Давайте кратко рассмотрим таблицу пользователей .
Теперь вы можете видеть, что столбцы в таблице AspNetUsers включают столбцы для хранения всех тех свойств, которые мы видели в Identity User, от которого мы унаследовали, и его полей, таких как UserName и PasswordHash. Итак, вы использовали некоторые из встроенных служб идентификации, поскольку они также содержат возможность создания пользователя и проверки пароля пользователя.
ASP.NET Core — регистрация пользователей
В этой главе мы обсудим регистрацию пользователя. Теперь у нас есть рабочая база данных, и пришло время начать добавлять некоторые функции в приложение. Мы также настроили наше приложение, и у нас есть рабочая схема базы данных. Давайте теперь перейдем на домашнюю страницу приложения.
Откройте инструменты разработчика, нажав клавишу F12, а затем нажмите ссылку «Изменить». Ранее, когда мы нажимали на ссылку «Редактировать», платформа MVC обнаружила наличие атрибута Authorize и возвращала код состояния 401, поскольку пользователь не вошел в систему.
Теперь вы увидите, что мы получаем сообщение на экране из файла конфигурации.
Давайте теперь перейдем к инструментам разработчика.
-
Вы увидите, что браузер запросил страницу редактирования, и платформа MVC решила, что пользователь не авторизован для просмотра этого ресурса.
-
Таким образом, где-то внутри инфраструктуры MVC был сгенерирован код состояния 401.
-
Теперь у нас есть промежуточное ПО Identity. Промежуточное ПО Identity просматривает тот код состояния 401, который будет передаваться пользователю, и заменяет его кодом состояния 302, который представляет собой код состояния перенаправления.
-
Платформа Identity знает, что пользователь должен будет попытаться войти в систему, прежде чем он сможет достичь этого ресурса.
-
Платформа Identity направила нас на этот URL, как мы видим в адресной строке — / Account / Login.
-
Это настраиваемая конечная точка с платформой Identity внутри запуска, когда вы регистрируете эти службы и промежуточное программное обеспечение. Существуют различные параметры, которые вы можете установить, и один из них — изменить URL для входа.
-
По умолчанию URL будет / Account / Login. В настоящее время у нас нет контроллера учетных записей, поэтому в конечном итоге мы хотим создать контроллер учетных записей и позволить пользователю войти в систему.
-
Но прежде чем пользователи смогут войти, им нужно будет зарегистрироваться на сайте и сохранить свои имена пользователей и пароли.
-
Функции входа в систему и регистрации могут быть частью контроллера учетной записи.
Вы увидите, что браузер запросил страницу редактирования, и платформа MVC решила, что пользователь не авторизован для просмотра этого ресурса.
Таким образом, где-то внутри инфраструктуры MVC был сгенерирован код состояния 401.
Теперь у нас есть промежуточное ПО Identity. Промежуточное ПО Identity просматривает тот код состояния 401, который будет передаваться пользователю, и заменяет его кодом состояния 302, который представляет собой код состояния перенаправления.
Платформа Identity знает, что пользователь должен будет попытаться войти в систему, прежде чем он сможет достичь этого ресурса.
Платформа Identity направила нас на этот URL, как мы видим в адресной строке — / Account / Login.
Это настраиваемая конечная точка с платформой Identity внутри запуска, когда вы регистрируете эти службы и промежуточное программное обеспечение. Существуют различные параметры, которые вы можете установить, и один из них — изменить URL для входа.
По умолчанию URL будет / Account / Login. В настоящее время у нас нет контроллера учетных записей, поэтому в конечном итоге мы хотим создать контроллер учетных записей и позволить пользователю войти в систему.
Но прежде чем пользователи смогут войти, им нужно будет зарегистрироваться на сайте и сохранить свои имена пользователей и пароли.
Функции входа в систему и регистрации могут быть частью контроллера учетной записи.
Давайте теперь продвинемся и добавим новый класс в папку Controllers, и назовем его AccountController. Мы выведем это из базового класса Controller инфраструктуры MVC.
using Microsoft.AspNet.Mvc; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Threading.Tasks; namespace FirstAppDemo.Controllers { public class AccountController : Controller { } }
-
Теперь нам нужно настроить функцию, с помощью которой пользователь может зарегистрироваться на этом сайте.
-
Это будет очень похоже на форму редактирования.
-
Когда пользователь хочет зарегистрироваться, мы сначала отобразим форму, которая позволяет ему заполнить необходимую информацию. Затем они могут загрузить эту форму на сайт.
-
Эта информация затем сохраняется в базе данных.
Теперь нам нужно настроить функцию, с помощью которой пользователь может зарегистрироваться на этом сайте.
Это будет очень похоже на форму редактирования.
Когда пользователь хочет зарегистрироваться, мы сначала отобразим форму, которая позволяет ему заполнить необходимую информацию. Затем они могут загрузить эту форму на сайт.
Эта информация затем сохраняется в базе данных.
Теперь давайте создадим действие, которое будет возвращать представление, когда мы перейдем в / account / register.
public class AccountController : Controller { [HttpGet] public ViewResult Register() { return View(); } }
Нам не нужно ничего искать, пользователь предоставит всю необходимую нам информацию. Прежде чем мы создадим ViewModel для этого представления, нам нужно определиться с информацией, которую будет отображать представление. Нам также нужно определиться с информацией, которую нам нужно будет получить от пользователя?
Давайте создадим модель представления для этого сценария, добавив новый класс в файл AccountController.cs и назовем его RegisterViewModel.
Давайте создадим некоторые свойства, которые будут содержать имя пользователя, пароль, а также пользователя ConfirmPassword, введя его дважды и убедившись, что оба пароля совпадают, как показано в следующей программе.
public class RegisterViewModel { [Required, MaxLength(256)] public string Username { get; set; } [Required, DataType(DataType.Password)] public string Password { get; set; } [DataType(DataType.Password), Compare(nameof(Password))] public string ConfirmPassword { get; set; } }
В приведенном выше классе вы можете увидеть некоторые аннотации, которые могут помочь нам проверить эту модель. Здесь требуется имя пользователя, и если вы посмотрите на схему базы данных, столбец для хранения имени пользователя будет содержать 256 символов.
-
Мы также применим здесь атрибут MaxLength.
-
Пароль будет требоваться, и когда мы представляем ввод для этого пароля, мы хотим, чтобы тип ввода был Тип пароля, чтобы символы не отображались на экране.
-
Пароль подтверждения также будет паролем типа данных, а затем будет добавлен дополнительный атрибут сравнения. Мы сравним поле ConfirmPassword с этим другим свойством, которое мы можем указать, а именно с полем Password.
Мы также применим здесь атрибут MaxLength.
Пароль будет требоваться, и когда мы представляем ввод для этого пароля, мы хотим, чтобы тип ввода был Тип пароля, чтобы символы не отображались на экране.
Пароль подтверждения также будет паролем типа данных, а затем будет добавлен дополнительный атрибут сравнения. Мы сравним поле ConfirmPassword с этим другим свойством, которое мы можем указать, а именно с полем Password.
Давайте теперь создадим представление, которое нам нужно. Нам нужно будет добавить новую папку к представлениям и назвать ее Account, поэтому все представления, связанные с AccountController, будут добавлены в эту папку.
Теперь щелкните правой кнопкой мыши папку «Учетная запись» и выберите «Добавить» → «Новый элемент».
В средней панели выберите страницу просмотра MVC и назовите ее Register.cshtml, а затем нажмите кнопку «Добавить».
Удалите все существующие коды из файла Register.cshtml и добавьте следующий код.
@model RegisterViewModel @{ ViewBag.Title = "Register"; } <h1>Register</h1> <form method = "post" asp-controller = "Account" asp-action = "Register"> <div asp-validation-summary = "ValidationSummary.ModelOnly"></div> <div> <label asp-for = "Username"></label> <input asp-for = "Username" /> <span asp-validation-for = "Username"></span> </div> <div> <label asp-for = "Password"></label> <input asp-for = "Password" /> <span asp-validation-for = "Password"></span> </div> <div> <label asp-for = "ConfirmPassword"></label> <input asp-for = "ConfirmPassword" /> <span asp-validation-for = "ConfirmPassword"></span> </div> <div> <input type = "submit" value = "Register" /> </div> </form>
-
Теперь вы можете видеть, что мы указали модель как RegisterViewModel, которую мы только что создали.
-
Мы также установим заголовок для этой страницы, используя ViewBag, и мы хотим, чтобы заголовок был Register.
-
Нам также нужно создать форму, которая содержит поля для имени пользователя, пароля и пароля ConfirmPassword.
-
Мы также включили div, который будет отображать сводку проверки. Когда мы используем сводку проверки ASP, нам необходимо указать, какие ошибки должны появляться в сводке.
-
Мы можем сделать так, чтобы все ошибки отображались в области сводки, или мы можем сказать ValidationSummary.ModelOnly, и единственными ошибками, которые будут появляться при проверке модели внутри сводки, будут ошибки проверки, связанные с моделью, а не конкретное свойство эта модель.
-
Другими словами, если пользователи не заполняют свое имя пользователя, но имя пользователя является обязательным, и для этого конкретного свойства будет ошибка проверки.
-
Но вы также можете генерировать ошибки модели, которые не связаны с определенным свойством, и они будут отображаться в этом ValidationSummary.
-
Внутри тега <form> у нас есть метки и входные данные для всех различных полей, которые есть в нашей ViewModel.
-
Нам нужен ярлык для имени пользователя, ввод для имени пользователя, а также сообщения для проверки правильности имени пользователя.
-
Два других свойства, которые нам нужно ввести пользователю, одинаковы и будут иметь метку и ввод, а также интервал для пароля и метку, а также ввод и интервал для ConfirmPassword.
-
Нам не нужно указывать типы ввода для пароля и ConfirmPassword, потому что помощник по тегу asp for будет обязательно устанавливать этот тип ввода в качестве пароля для нас.
-
В конце у нас должна быть кнопка с надписью Register . Когда пользователь нажимает на эту кнопку, мы отправляем форму обратно контроллеру.
Теперь вы можете видеть, что мы указали модель как RegisterViewModel, которую мы только что создали.
Мы также установим заголовок для этой страницы, используя ViewBag, и мы хотим, чтобы заголовок был Register.
Нам также нужно создать форму, которая содержит поля для имени пользователя, пароля и пароля ConfirmPassword.
Мы также включили div, который будет отображать сводку проверки. Когда мы используем сводку проверки ASP, нам необходимо указать, какие ошибки должны появляться в сводке.
Мы можем сделать так, чтобы все ошибки отображались в области сводки, или мы можем сказать ValidationSummary.ModelOnly, и единственными ошибками, которые будут появляться при проверке модели внутри сводки, будут ошибки проверки, связанные с моделью, а не конкретное свойство эта модель.
Другими словами, если пользователи не заполняют свое имя пользователя, но имя пользователя является обязательным, и для этого конкретного свойства будет ошибка проверки.
Но вы также можете генерировать ошибки модели, которые не связаны с определенным свойством, и они будут отображаться в этом ValidationSummary.
Внутри тега <form> у нас есть метки и входные данные для всех различных полей, которые есть в нашей ViewModel.
Нам нужен ярлык для имени пользователя, ввод для имени пользователя, а также сообщения для проверки правильности имени пользователя.
Два других свойства, которые нам нужно ввести пользователю, одинаковы и будут иметь метку и ввод, а также интервал для пароля и метку, а также ввод и интервал для ConfirmPassword.
Нам не нужно указывать типы ввода для пароля и ConfirmPassword, потому что помощник по тегу asp for будет обязательно устанавливать этот тип ввода в качестве пароля для нас.
В конце у нас должна быть кнопка с надписью Register . Когда пользователь нажимает на эту кнопку, мы отправляем форму обратно контроллеру.
В AccountController нам также необходимо реализовать метод действия HttpPost Register. Давайте вернемся к AccountController и добавим следующее действие Register следующим образом:
[HttpPost] public IActionResult Register (RegisterViewModel model) { }
Этот метод действия вернет IActionResult. Это получит RegisterViewModel. Теперь нам нужно взаимодействовать с платформой Identity, чтобы убедиться, что пользователь является действительным, сообщить платформе Identity о создании этого пользователя, а затем, поскольку он только что создал учетную запись, перейдите и войдите в него. Мы рассмотрим реализация всех этих шагов в следующей главе.
ASP.NET Core — создание пользователя
В этой главе мы обсудим, как создать пользователя. Чтобы продолжить, нам нужно взаимодействовать с платформой Identity, чтобы убедиться, что пользователь действителен, затем создать этого пользователя, а затем продолжить и войти в систему.
-
Существует две основные службы платформы Identity: одна — UserManager , а другая — SignInManager .
-
Нам нужно внедрить обе эти службы в наш контроллер. При этом мы можем вызывать соответствующие API, когда нам нужно создать пользователя или войти в систему.
-
Давайте добавим приватные переменные для SignInManager и UserManager, а затем добавим конструктор в ваш AccountController, который будет принимать два параметра UserManager типа User и SignInManager типа User.
Существует две основные службы платформы Identity: одна — UserManager , а другая — SignInManager .
Нам нужно внедрить обе эти службы в наш контроллер. При этом мы можем вызывать соответствующие API, когда нам нужно создать пользователя или войти в систему.
Давайте добавим приватные переменные для SignInManager и UserManager, а затем добавим конструктор в ваш AccountController, который будет принимать два параметра UserManager типа User и SignInManager типа User.
private SignInManager<User> _signManager; private UserManager<User> _userManager; public AccountController(UserManager<User> userManager, SignInManager<User> signManager){ _userManager = userManager; _signManager = signManager; }
-
Мы продолжим с методом действия POST AccountController, и одна из первых проверок, которую мы всегда должны делать внутри действия post, — это проверка, является ли наш ModelState действительным.
-
Если ModelState действителен, то мы знаем, что пользователь дал нам имя пользователя и пароль и подтвердил пароль; если нет, мы должны попросить их предоставить правильную информацию.
-
Вот реализация действия Регистра.
Мы продолжим с методом действия POST AccountController, и одна из первых проверок, которую мы всегда должны делать внутри действия post, — это проверка, является ли наш ModelState действительным.
Если ModelState действителен, то мы знаем, что пользователь дал нам имя пользователя и пароль и подтвердил пароль; если нет, мы должны попросить их предоставить правильную информацию.
Вот реализация действия Регистра.
[HttpPost] public async Task<IActionResult> Register(RegisterViewModel model) { if (ModelState.IsValid) { var user = new User { UserName = model.Username }; var result = await _userManager.CreateAsync(user, model.Password); if (result.Succeeded) { await _signManager.SignInAsync(user, false); return RedirectToAction("Index", "Home"); } else { foreach (var error in result.Errors) { ModelState.AddModelError("", error.Description); } } } return View(); }
-
Если наш ModelState действителен, нам нужно поговорить с платформой Identity. Нам также необходимо создать новый экземпляр нашей сущности User и скопировать наш входной файл model.Username в свойство UserName сущности User.
-
Но мы не собираемся копировать пароль, потому что нет места для хранения обычного текстового пароля в объекте User. Вместо этого мы передадим пароль непосредственно в инфраструктуру Identity, которая будет хэшировать пароль.
-
Итак, у нас есть userManager. Создайте метод Async, в котором мы должны передать имя пользователя, чтобы мы могли сохранить пароль для этого пользователя.
-
Этот метод Async возвращает результат, который сообщает нам, был ли экземпляр успешным или неудачным, и если он потерпел неудачу, он даст нам несколько возможных причин, по которым произошел сбой.
-
Если результат успешен, мы можем войти в систему пользователя, который только что создал учетную запись, а затем попросить SignInManager подписать этого пользователя. Теперь перенаправьте пользователя обратно на домашнюю страницу, и вы будете аутентифицированы.
-
Если результат не был успешным, то мы должны попытаться сообщить пользователю, почему, и результат, возвращаемый из UserManager, содержит набор ошибок, которые мы можем повторить и добавить эти ошибки в ModelState. Эти ошибки будут доступны в представлении для помощников тегов, таких как помощники тегов проверки, для отображения информации на странице.
-
В ModelState.AddModelError мы можем предоставить ключ, чтобы связать ошибку с конкретным полем. Мы также будем использовать пустую строку и добавим описание предоставленной ошибки.
Если наш ModelState действителен, нам нужно поговорить с платформой Identity. Нам также необходимо создать новый экземпляр нашей сущности User и скопировать наш входной файл model.Username в свойство UserName сущности User.
Но мы не собираемся копировать пароль, потому что нет места для хранения обычного текстового пароля в объекте User. Вместо этого мы передадим пароль непосредственно в инфраструктуру Identity, которая будет хэшировать пароль.
Итак, у нас есть userManager. Создайте метод Async, в котором мы должны передать имя пользователя, чтобы мы могли сохранить пароль для этого пользователя.
Этот метод Async возвращает результат, который сообщает нам, был ли экземпляр успешным или неудачным, и если он потерпел неудачу, он даст нам несколько возможных причин, по которым произошел сбой.
Если результат успешен, мы можем войти в систему пользователя, который только что создал учетную запись, а затем попросить SignInManager подписать этого пользователя. Теперь перенаправьте пользователя обратно на домашнюю страницу, и вы будете аутентифицированы.
Если результат не был успешным, то мы должны попытаться сообщить пользователю, почему, и результат, возвращаемый из UserManager, содержит набор ошибок, которые мы можем повторить и добавить эти ошибки в ModelState. Эти ошибки будут доступны в представлении для помощников тегов, таких как помощники тегов проверки, для отображения информации на странице.
В ModelState.AddModelError мы можем предоставить ключ, чтобы связать ошибку с конкретным полем. Мы также будем использовать пустую строку и добавим описание предоставленной ошибки.
Давайте сохраним все файлы и запустим приложение и перейдем в / account / register .
Давайте введем имя пользователя и очень простой 5-значный пароль.
Теперь нажмите кнопку Зарегистрироваться.
По умолчанию платформа Identity пытается применить некоторые правила к паролям.
Пароли должны содержать не менее 6 символов, один символ должен быть в нижнем регистре, один должен быть в верхнем регистре, и должен быть один нецифровый символ.
Причина, по которой эти ошибки появляются здесь, заключается в том, что у нас есть сводка проверки на странице, которая собирает ошибки, возвращаемые из результата userManager.CreateAsync .
Теперь, когда мы немного больше узнали о правилах паролей, давайте попробуем создать достаточно сложный пароль и нажать Зарегистрировать.
Теперь вы увидите домашнюю страницу. Это значит, что операция сработала. Теперь перейдем к обозревателю объектов SQL Server.
Щелкните правой кнопкой мыши таблицу dbo.AspNetUsers и выберите « Просмотр данных» .
Теперь вы можете видеть, что пользователь был успешно создан, а также вы можете увидеть новую запись в таблице Users. Вы также можете увидеть хешированное значение пароля, а также имя пользователя, и это имя пользователя, которое мы зарегистрировали в mark.upston .
ASP.NET Core — вход и выход
В этой главе мы обсудим функцию входа и выхода из системы. Выход из системы довольно прост по сравнению с входом в систему. Давайте продолжим с представлением Layout, потому что мы хотим создать пользовательский интерфейс, который имеет несколько ссылок. Это позволит зарегистрированному пользователю выйти из системы, а также отобразить имя пользователя.
<!DOCTYPE html> <html> <head> <meta name = "viewport" content = "width = device-width" /> <title>@ViewBag.Title</title> </head> <body> <div> @DateTime.Now </div> <div> @RenderBody() </div> </body> </html>
-
Для анонимного пользователя мы покажем ссылку для входа.
-
Вся информация, необходимая для создания этого пользовательского интерфейса, доступна в контексте представления Razor.
-
Во-первых, давайте добавим пространство имен System.Security.Claims в ваш макет.
Для анонимного пользователя мы покажем ссылку для входа.
Вся информация, необходимая для создания этого пользовательского интерфейса, доступна в контексте представления Razor.
Во-первых, давайте добавим пространство имен System.Security.Claims в ваш макет.
@using System.Security.Claims <!DOCTYPE html> <html> <head> <meta name = "viewport" content = "width = device-width" /> <title>@ViewBag.Title</title> </head> <body> <div> @if (User.IsSignedIn()) { <div>@User.GetUserName()</div> <form method = "post" asp-controller = "Account" aspcontroller = "Logout"> <input type = "submit" value = "Logout"/> </form> } else { <a asp-controller = "Account" asp-action = "Login">Login</a> <a asp-controller = "Account" asp-action = "Register">Register</a> } </div> <div> @DateTime.Now </div> <div> @RenderBody() </div> </body> </html>
-
В каждом представлении Razor есть свойство User, и мы хотим создать пользовательский интерфейс, который будет отображать имя пользователя, вошедшего в систему. Метод расширения IsSignedIn также доступен здесь.
-
Мы можем вызвать этот метод, и если он вернет true, мы можем разместить некоторую разметку для отображения имени пользователя, отобразить кнопку выхода из системы.
-
Теперь, если пользователь вошел в систему, мы можем отобразить имя пользователя, используя вспомогательный метод GetUserName .
-
Нам нужно будет встроить кнопку выхода из формы, которая будет размещена на веб-сервере. Это должно быть сделано, поскольку это создаст определенные нежелательные условия, если вы позволите простой запрос GET REQUEST, чтобы позволить пользователю выйти.
-
Мы сделаем так, чтобы это была публикация, и когда пользователь отправит эту форму, все, что нам нужно сделать, — это нажать на действие Logout, которое мы реализуем через AccountController, и выйти из системы пользователя.
-
Если пользователь не вошел в систему и у нас есть анонимный пользователь, то нам нужно показать ссылку, которая пойдет на AccountController, в частности на действие Login, и он может отобразить текст Login.
-
Нам также необходимо добавить ссылку для регистрации новых пользователей и перехода непосредственно на страницу регистрации.
В каждом представлении Razor есть свойство User, и мы хотим создать пользовательский интерфейс, который будет отображать имя пользователя, вошедшего в систему. Метод расширения IsSignedIn также доступен здесь.
Мы можем вызвать этот метод, и если он вернет true, мы можем разместить некоторую разметку для отображения имени пользователя, отобразить кнопку выхода из системы.
Теперь, если пользователь вошел в систему, мы можем отобразить имя пользователя, используя вспомогательный метод GetUserName .
Нам нужно будет встроить кнопку выхода из формы, которая будет размещена на веб-сервере. Это должно быть сделано, поскольку это создаст определенные нежелательные условия, если вы позволите простой запрос GET REQUEST, чтобы позволить пользователю выйти.
Мы сделаем так, чтобы это была публикация, и когда пользователь отправит эту форму, все, что нам нужно сделать, — это нажать на действие Logout, которое мы реализуем через AccountController, и выйти из системы пользователя.
Если пользователь не вошел в систему и у нас есть анонимный пользователь, то нам нужно показать ссылку, которая пойдет на AccountController, в частности на действие Login, и он может отобразить текст Login.
Нам также необходимо добавить ссылку для регистрации новых пользователей и перехода непосредственно на страницу регистрации.
Теперь давайте перейдем к AccountController и сначала осуществим действие выхода из системы, как в следующей программе.
[HttpPost] public async Task<IActionResult> Logout() { await _signManager.SignOutAsync(); return RedirectToAction("Index", "Home"); }
-
Это действие реагирует только на HttpPost. Это асинхронное действие. Нам нужно будет вызвать другой асинхронный метод на платформе Identity.
-
Мы можем вернуть задачу IActionResult, и действие называется Выход из системы.
-
Все, что нам нужно сделать, чтобы выйти из системы, это дождаться метода SignOutAsync от SignInManager .
-
Пользовательский контекст изменился; Теперь у нас есть анонимный пользователь. Представление будет перенаправлено на домашнюю страницу, и мы вернемся к списку сотрудников.
Это действие реагирует только на HttpPost. Это асинхронное действие. Нам нужно будет вызвать другой асинхронный метод на платформе Identity.
Мы можем вернуть задачу IActionResult, и действие называется Выход из системы.
Все, что нам нужно сделать, чтобы выйти из системы, это дождаться метода SignOutAsync от SignInManager .
Пользовательский контекст изменился; Теперь у нас есть анонимный пользователь. Представление будет перенаправлено на домашнюю страницу, и мы вернемся к списку сотрудников.
Давайте теперь продолжим и создадим функцию входа в систему. Здесь нам понадобится пара действий, одно из которых отвечает на запрос HttpGet и отображает форму, которую мы можем использовать для входа, а другое — на запрос HttpPost.
Для начала нам понадобится новая ViewModel, чтобы получить данные для входа, потому что вход в систему сильно отличается от регистрации. Итак, давайте добавим новый класс и назовем его LoginViewModel .
public class LoginViewModel { public string Username { get; set; } [DataType(DataType.Password)] public string Password { get; set; } [Display(Name ="Remember Me")] public bool RememberMe { get; set; } public string ReturnUrl { get; set; } }
-
Когда пользователи входят в систему, они должны предоставить некоторую информацию, такую как имя пользователя, пароль.
-
Третья часть информации должна быть интерфейсом входа в систему. Они поставляются с небольшим флажком, который говорит: «Хочешь запомнить меня». Это выбор между тем, хотим ли мы использовать файл cookie сеанса или нам нужен более постоянный файл cookie.
-
Чтобы разрешить эту функцию, мы добавили логическое свойство RememberMe и использовали аннотацию Display. Теперь, когда мы создаем ярлык, текст « Помни меня» отображается с пробелом.
-
Последняя информация, которую мы на самом деле хотим получить как часть этой ViewModel, — это иметь свойство, в котором будет храниться ReturnUrl.
Когда пользователи входят в систему, они должны предоставить некоторую информацию, такую как имя пользователя, пароль.
Третья часть информации должна быть интерфейсом входа в систему. Они поставляются с небольшим флажком, который говорит: «Хочешь запомнить меня». Это выбор между тем, хотим ли мы использовать файл cookie сеанса или нам нужен более постоянный файл cookie.
Чтобы разрешить эту функцию, мы добавили логическое свойство RememberMe и использовали аннотацию Display. Теперь, когда мы создаем ярлык, текст « Помни меня» отображается с пробелом.
Последняя информация, которую мы на самом деле хотим получить как часть этой ViewModel, — это иметь свойство, в котором будет храниться ReturnUrl.
Теперь давайте добавим действие входа в систему, которое будет отвечать на запрос Get, как показано в следующей программе.
[HttpGet] public IActionResult Login(string returnUrl = "") { var model = new LoginViewModel { ReturnUrl = returnUrl }; return View(model); }
-
Мы возьмем returnUrl в качестве параметра, который находится в строке запроса.
-
ReturnUrl не всегда может быть там. Давайте по умолчанию будем иметь пустую строку.
Мы возьмем returnUrl в качестве параметра, который находится в строке запроса.
ReturnUrl не всегда может быть там. Давайте по умолчанию будем иметь пустую строку.
Теперь у нас будет новое представление, добавив новую страницу просмотра MVC в папке Views → Account .
В средней панели выберите страницу просмотра MVC и назовите ее Login.cshtml, а затем нажмите кнопку «Добавить». Давайте добавим следующий код в файл Login.cshtml.
@model LoginViewModel @{ ViewBag.Title = "Login"; } <h2>Login</h2> <form method = "post" asp-controller = "Account" asp-action = "Login" asp-route-returnurl = "@Model.ReturnUrl"> <div asp-validation-summary = "ValidationSummary.ModelOnly"></div> <div> <label asp-for = "Username"></label> <input asp-for = "Username" /> <span asp-validation-for = "Username"></span> </div> <div> <label asp-for = "Password"></label> <input asp-for = "Password" /> <span asp-validation-for = "Password"></span> </div> <div> <label asp-for = "RememberMe"></label> <input asp-for = "RememberMe" /> <span asp-validation-for = "RememberMe"></span> </div> <input type = "submit" value = "Login" /> </form>
-
В этом представлении входа в систему мы установили заголовок страницы на «Вход», а затем у нас есть форма, которая будет публиковать действие AccountLogin .
-
Нам нужно использовать помощник по тегам asp-route-returnurl , чтобы убедиться, что ReturnUrl присутствует в URL -адресе , на который отправляется форма.
-
Нам нужно отправить этот ReturnUrl обратно на сервер, чтобы, если пользователь успешно вошел в систему, мы могли отправить его туда, куда он пытался добраться.
-
Все, что вы добавляете после asp-route-, id или returnurl, все, что у вас там есть, будет куда-то идти в запросе, либо в URL-пути, либо в качестве параметра строки запроса.
-
У нас есть ValidationSummary и входные данные для имени пользователя, пароля и RememberMe, а затем у нас есть кнопка «Отправить».
В этом представлении входа в систему мы установили заголовок страницы на «Вход», а затем у нас есть форма, которая будет публиковать действие AccountLogin .
Нам нужно использовать помощник по тегам asp-route-returnurl , чтобы убедиться, что ReturnUrl присутствует в URL -адресе , на который отправляется форма.
Нам нужно отправить этот ReturnUrl обратно на сервер, чтобы, если пользователь успешно вошел в систему, мы могли отправить его туда, куда он пытался добраться.
Все, что вы добавляете после asp-route-, id или returnurl, все, что у вас там есть, будет куда-то идти в запросе, либо в URL-пути, либо в качестве параметра строки запроса.
У нас есть ValidationSummary и входные данные для имени пользователя, пароля и RememberMe, а затем у нас есть кнопка «Отправить».
` AccountController и реализовать действие Post. Это действие, которое отвечает на HttpPost. Это будет метод Async, потому что нам нужно будет вызвать инфраструктуру Identity и вернуть задачу или IActionResult.
[HttpPost] public async Task<IActionResult> Login(LoginViewModel model) { if (ModelState.IsValid) { var result = await _signManager.PasswordSignInAsync(model.Username, model.Password, model.RememberMe,false); if (result.Succeeded) { if (!string.IsNullOrEmpty(model.ReturnUrl) && Url.IsLocalUrl(model.ReturnUrl)) { return Redirect(model.ReturnUrl); } else { return RedirectToAction("Index", "Home"); } } } ModelState.AddModelError("","Invalid login attempt"); return View(model); }
-
Мы называем это Login, и теперь мы ожидаем получить LoginViewModel.
-
Нам нужно проверить, действительно ли ModelState. Если это действительно так, то войдите в систему, вызвав API на SignInManager.
-
Метод PasswordSignInAsync вернет результат, и если результат был успешным, мы знаем, что пользователь успешно вошел в систему.
-
У нас также есть обратный URL. Если это действительный локальный URL, мы будем перенаправлены на обратный URL.
-
Если пользователь только что вошел в систему и не имеет определенного места для перехода, мы перенаправим пользователя к действию Index HomeController.
-
Мы можем быть в ситуации, когда пользователь вводит неверный пароль или неверное имя пользователя. Нам также нужно добавить модельную ошибку, которая запрашивает, есть ли попытка неверного входа в систему. Это помогает пользователю узнать, если что-то пошло не так.
Мы называем это Login, и теперь мы ожидаем получить LoginViewModel.
Нам нужно проверить, действительно ли ModelState. Если это действительно так, то войдите в систему, вызвав API на SignInManager.
Метод PasswordSignInAsync вернет результат, и если результат был успешным, мы знаем, что пользователь успешно вошел в систему.
У нас также есть обратный URL. Если это действительный локальный URL, мы будем перенаправлены на обратный URL.
Если пользователь только что вошел в систему и не имеет определенного места для перехода, мы перенаправим пользователя к действию Index HomeController.
Мы можем быть в ситуации, когда пользователь вводит неверный пароль или неверное имя пользователя. Нам также нужно добавить модельную ошибку, которая запрашивает, есть ли попытка неверного входа в систему. Это помогает пользователю узнать, если что-то пошло не так.
Давайте теперь все сохраним и запустим приложение.
Теперь у нас есть ссылки для входа и регистрации. Давайте перейдем по ссылке «Войти».
Давайте войдем в систему с пользователем, которого мы создали в предыдущей главе, указав имя пользователя и пароль, и установите флажок Запомнить меня .
Когда вы нажимаете кнопку «Вход», браузер спросит вас, хотите ли вы сохранить пароль для локального хоста. Давайте нажмем на кнопку «Да».
Теперь давайте выйдем из системы, нажав кнопку «Выйти».
Как анонимный пользователь, давайте попробуем отредактировать данные сотрудника.
Теперь вы можете видеть, что мы были перенаправлены на страницу входа в систему .
Позвольте нам войти в систему с вашим именем пользователя и паролем и установить флажок Запомнить меня.
Теперь нажмите кнопку «Войти».
Теперь вы можете видеть, что мы перенаправлены на URL, который мы хотим изменить. Это потому, что мы обработали обратный URL соответствующим образом.