From e558327e815b8cc80bc51e0c3619118cfa5b33f8 Mon Sep 17 00:00:00 2001 From: "ns.potapov" Date: Wed, 29 May 2024 02:22:44 +0400 Subject: [PATCH] =?UTF-8?q?=D0=A0=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=D0=B5?= =?UTF-8?q?=D1=82=20=D1=80=D0=B5=D0=B3=D0=B8=D1=81=D1=82=D1=80=D0=B0=D1=86?= =?UTF-8?q?=D0=B8=D1=8F,=20=D0=BB=D0=BE=D0=B3=D0=B8=D0=BD=20=D0=B8=20?= =?UTF-8?q?=D1=80=D0=B0=D0=B7=D0=BB=D0=BE=D0=B3=D0=B8=D0=BD=20=D0=B8=D1=81?= =?UTF-8?q?=D0=BF=D0=BE=D0=BB=D0=BD=D0=B8=D1=82=D0=B5=D0=BB=D1=8F,=20?= =?UTF-8?q?=D1=81=D0=B4=D0=B5=D0=BB=D0=B0=D0=BD=D1=8B=20=D0=BF=D1=80=D0=BE?= =?UTF-8?q?=D0=B2=D0=B5=D1=80=D0=BA=D0=B8=20=D0=BD=D0=B0=20=D0=B7=D0=B0?= =?UTF-8?q?=D0=BB=D0=BE=D0=B3=D0=B8=D0=BD=D0=B5=D0=BD=D0=BE=D0=B3=D0=BE=20?= =?UTF-8?q?=D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5?= =?UTF-8?q?=D0=BB=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Implements/UserStorage.cs | 19 ++-- .../Controllers/CoursesController.cs | 20 ++++ .../Controllers/DiagnosesController.cs | 40 ++++++-- .../Controllers/HomeController.cs | 51 ---------- .../Controllers/SymptomesController.cs | 20 ++++ .../Controllers/UserController.cs | 98 +++++++++++++++++++ .../LoginManager.cs | 9 ++ .../Models/LoginModel.cs | 9 ++ .../Models/RegisterModel.cs | 11 +++ .../PolyclinicWebAppImplementer.csproj | 4 +- .../PolyclinicWebAppImplementer/Program.cs | 3 + .../RestrictionEnum.cs | 9 ++ .../SiteMenuItems.cs | 22 ++--- .../Views/Shared/_Layout.cshtml | 33 ++++--- .../Views/{Home => User}/Login.cshtml | 13 ++- .../Views/{Home => User}/Register.cshtml | 23 ++++- 16 files changed, 288 insertions(+), 96 deletions(-) create mode 100644 Polyclinic/PolyclinicWebAppImplementer/Controllers/UserController.cs create mode 100644 Polyclinic/PolyclinicWebAppImplementer/LoginManager.cs create mode 100644 Polyclinic/PolyclinicWebAppImplementer/Models/LoginModel.cs create mode 100644 Polyclinic/PolyclinicWebAppImplementer/Models/RegisterModel.cs create mode 100644 Polyclinic/PolyclinicWebAppImplementer/RestrictionEnum.cs rename Polyclinic/PolyclinicWebAppImplementer/Views/{Home => User}/Login.cshtml (61%) rename Polyclinic/PolyclinicWebAppImplementer/Views/{Home => User}/Register.cshtml (50%) diff --git a/Polyclinic/PolyclinicDatabaseImplement/Implements/UserStorage.cs b/Polyclinic/PolyclinicDatabaseImplement/Implements/UserStorage.cs index 657634a..a60d0cd 100644 --- a/Polyclinic/PolyclinicDatabaseImplement/Implements/UserStorage.cs +++ b/Polyclinic/PolyclinicDatabaseImplement/Implements/UserStorage.cs @@ -31,13 +31,20 @@ namespace PolyclinicDatabaseImplement.Implements public List GetFilteredList(UserSearchModel model) { var elements = GetFullList(); - foreach (var prop in model.GetType().GetProperties()) + if (model.Id != null) { - if (model.GetType().GetProperty(prop.Name)?.GetValue(model, null) != null) - { - elements = elements.Where(x => x.GetType().GetProperty(prop.Name)?.GetValue(x, null) == model.GetType().GetProperty(prop.Name)?.GetValue(model, null)).ToList(); - } - } + elements = elements.Where(x => x.Id == model.Id).ToList(); + } + if (!model.Email.IsNullOrEmpty()) + { + elements = elements.Where(x => x.Email == model.Email).ToList(); + + } + if (!model.Password.IsNullOrEmpty()) + { + elements = elements.Where(x => x.Password == model.Password).ToList(); + + } return elements; } diff --git a/Polyclinic/PolyclinicWebAppImplementer/Controllers/CoursesController.cs b/Polyclinic/PolyclinicWebAppImplementer/Controllers/CoursesController.cs index 4ed72b6..4d92f34 100644 --- a/Polyclinic/PolyclinicWebAppImplementer/Controllers/CoursesController.cs +++ b/Polyclinic/PolyclinicWebAppImplementer/Controllers/CoursesController.cs @@ -22,6 +22,11 @@ namespace PolyclinicWebAppImplementer.Controllers [HttpGet] public IActionResult Index() { + var currentUser = LoginManager.LogginedUser; + if (currentUser == null) + { + return RedirectToAction("Login", "User"); + } List courses = _courseLogic.ReadList(); ViewData["Title"] = "Список курсов"; return View("CoursesList", courses); @@ -30,6 +35,11 @@ namespace PolyclinicWebAppImplementer.Controllers [HttpPost] public IActionResult Add(CourseFormModel model, int[] selectedDiagnoses) { + var currentUser = LoginManager.LogginedUser; + if (currentUser == null) + { + return RedirectToAction("Login", "User"); + } if (HttpContext.Request.Method == "GET") { ViewData["Title"] = "Новый курс"; @@ -61,6 +71,11 @@ namespace PolyclinicWebAppImplementer.Controllers [HttpPost] public IActionResult Edit(int id, CourseFormModel model, int[] selectedDiagnoses) { + var currentUser = LoginManager.LogginedUser; + if (currentUser == null) + { + return RedirectToAction("Login", "User"); + } if (HttpContext.Request.Method == "GET") { var obj = _courseLogic.ReadElement(new CourseSearchModel { Id = id }); @@ -94,6 +109,11 @@ namespace PolyclinicWebAppImplementer.Controllers [HttpPost] public IActionResult Delete(int id) { + var currentUser = LoginManager.LogginedUser; + if (currentUser == null) + { + return RedirectToAction("Login", "User"); + } var obj = _courseLogic.ReadElement(new CourseSearchModel { Id = id }); if (obj != null) { diff --git a/Polyclinic/PolyclinicWebAppImplementer/Controllers/DiagnosesController.cs b/Polyclinic/PolyclinicWebAppImplementer/Controllers/DiagnosesController.cs index 0793cbb..4e84b9d 100644 --- a/Polyclinic/PolyclinicWebAppImplementer/Controllers/DiagnosesController.cs +++ b/Polyclinic/PolyclinicWebAppImplementer/Controllers/DiagnosesController.cs @@ -4,6 +4,7 @@ using PolyclinicContracts.BusinessLogicsContracts; using PolyclinicContracts.SearchModels; using PolyclinicContracts.ViewModels; using PolyclinicWebAppImplementer.Models; +using System.Net; namespace PolyclinicWebAppImplementer.Controllers { @@ -21,8 +22,12 @@ namespace PolyclinicWebAppImplementer.Controllers [HttpGet] public IActionResult Index() { - // TODO выводить только пользовательские диагнозы - List diagnoses = _diagnoseLogic.ReadList(); + var currentUser = LoginManager.LogginedUser; + if (currentUser == null) + { + return RedirectToAction("Login", "User"); + } + List diagnoses = _diagnoseLogic.ReadList(new DiagnoseSearchModel { UserId = currentUser.Id }); ViewData["Title"] = "Список диагнозов"; return View("DiagnosesList", diagnoses); } @@ -31,6 +36,11 @@ namespace PolyclinicWebAppImplementer.Controllers [HttpPost] public IActionResult Add(DiagnoseViewModel model) { + var currentUser = LoginManager.LogginedUser; + if (currentUser == null) + { + return RedirectToAction("Login", "User"); + } if (HttpContext.Request.Method == "GET") { ViewData["Title"] = "Новый диагноз"; @@ -38,9 +48,9 @@ namespace PolyclinicWebAppImplementer.Controllers } else { - // TODO прописать UserId DiagnoseBindingModel diagnose = new DiagnoseBindingModel { + UserId = currentUser.Id, Name = model.Name, Comment = model.Comment, DateStartDiagnose = model.DateStartDiagnose, @@ -48,17 +58,25 @@ namespace PolyclinicWebAppImplementer.Controllers }; _diagnoseLogic.Create(diagnose); return RedirectToAction("Index"); - } + } } [HttpGet] [HttpPost] public IActionResult Edit(int id, DiagnoseViewModel model) { - // TODO проверить, что пользователь хочет редактировать свой диагноз (UserId) + var currentUser = LoginManager.LogginedUser; + if (currentUser == null) + { + return RedirectToAction("Login", "User"); + } + var obj = _diagnoseLogic.ReadElement(new DiagnoseSearchModel { Id = id }); + if (obj.UserId != currentUser.Id) + { + return StatusCode(403, "Нельзя редактировать чужой диагноз"); + } if (HttpContext.Request.Method == "GET") { - var obj = _diagnoseLogic.ReadElement(new DiagnoseSearchModel { Id = id }); ViewData["Title"] = "Редактировать диагноз"; return View("DiagnoseForm", obj); } @@ -80,8 +98,16 @@ namespace PolyclinicWebAppImplementer.Controllers [HttpPost] public IActionResult Delete(int id) { - // TODO проверить, что пользователь хочет удалить свой диагноз (UserId) + var currentUser = LoginManager.LogginedUser; + if (currentUser == null) + { + return RedirectToAction("Login", "User"); + } var obj = _diagnoseLogic.ReadElement(new DiagnoseSearchModel { Id = id }); + if (obj.UserId != currentUser.Id) + { + return StatusCode(403, "Нельзя удалить чужой диагноз"); + } if (obj != null) { _diagnoseLogic.Delete(new DiagnoseBindingModel { Id = obj.Id }); diff --git a/Polyclinic/PolyclinicWebAppImplementer/Controllers/HomeController.cs b/Polyclinic/PolyclinicWebAppImplementer/Controllers/HomeController.cs index 62aa1e5..157d1c1 100644 --- a/Polyclinic/PolyclinicWebAppImplementer/Controllers/HomeController.cs +++ b/Polyclinic/PolyclinicWebAppImplementer/Controllers/HomeController.cs @@ -17,63 +17,12 @@ namespace PolyclinicWebAppImplementer.Controllers { return View(); } - [HttpGet] - [HttpPost] - public IActionResult Course() - { - if (HttpContext.Request.Method == "POST") - { - return Redirect("~/Home/Courses"); - } - else - { - return View(); - } - } - public IActionResult Courses() - { - return View(); - } - public IActionResult Symptom() - { - if (HttpContext.Request.Method == "POST") - { - return Redirect("~/Home/Symptomes"); - } - else - { - return View(); - } - } - public IActionResult Symptomes() - { - return View(); - } public IActionResult Privacy() { return View(); } - [HttpGet] - [HttpPost] - public IActionResult Login() - { - if (HttpContext.Request.Method == "POST") - { - return Redirect("~/"); - } - else - { - return View(); - } - } - - public IActionResult Register() - { - return View(); - } - [HttpGet] [HttpPost] public IActionResult AddRecipeToCourse() diff --git a/Polyclinic/PolyclinicWebAppImplementer/Controllers/SymptomesController.cs b/Polyclinic/PolyclinicWebAppImplementer/Controllers/SymptomesController.cs index 8578b12..6ff0b44 100644 --- a/Polyclinic/PolyclinicWebAppImplementer/Controllers/SymptomesController.cs +++ b/Polyclinic/PolyclinicWebAppImplementer/Controllers/SymptomesController.cs @@ -20,6 +20,11 @@ namespace PolyclinicWebAppImplementer.Controllers [HttpGet] public IActionResult Index() { + var currentUser = LoginManager.LogginedUser; + if (currentUser == null) + { + return RedirectToAction("Login", "User"); + } List symptomes = _symptomLogic.ReadList(); ViewData["Title"] = "Список симптомов"; return View("SymptomesList", symptomes); @@ -28,6 +33,11 @@ namespace PolyclinicWebAppImplementer.Controllers [HttpPost] public IActionResult Add(SymptomFormModel model, int[] selectedDiagnoses) { + var currentUser = LoginManager.LogginedUser; + if (currentUser == null) + { + return RedirectToAction("Login", "User"); + } if (HttpContext.Request.Method == "GET") { ViewData["Title"] = "Новый симптом"; @@ -58,6 +68,11 @@ namespace PolyclinicWebAppImplementer.Controllers [HttpPost] public IActionResult Edit(int id, SymptomFormModel model, int[] selectedDiagnoses) { + var currentUser = LoginManager.LogginedUser; + if (currentUser == null) + { + return RedirectToAction("Login", "User"); + } if (HttpContext.Request.Method == "GET") { var obj = _symptomLogic.ReadElement(new SymptomSearchModel { Id = id }); @@ -90,6 +105,11 @@ namespace PolyclinicWebAppImplementer.Controllers [HttpPost] public IActionResult Delete(int id) { + var currentUser = LoginManager.LogginedUser; + if (currentUser == null) + { + return RedirectToAction("Login", "User"); + } var obj = _symptomLogic.ReadElement(new SymptomSearchModel { Id = id }); if (obj != null) { diff --git a/Polyclinic/PolyclinicWebAppImplementer/Controllers/UserController.cs b/Polyclinic/PolyclinicWebAppImplementer/Controllers/UserController.cs new file mode 100644 index 0000000..3748432 --- /dev/null +++ b/Polyclinic/PolyclinicWebAppImplementer/Controllers/UserController.cs @@ -0,0 +1,98 @@ +using Microsoft.AspNetCore.Mvc; +using PolyclinicContracts.BindingModels; +using PolyclinicContracts.BusinessLogicsContracts; +using PolyclinicContracts.SearchModels; +using PolyclinicDataModels.Enums; +using PolyclinicDataModels.Models; +using PolyclinicWebAppImplementer.Models; + +namespace PolyclinicWebAppImplementer.Controllers +{ + public class UserController : Controller + { + private readonly IUserLogic _userLogic; + public UserController(IUserLogic userLogic) + { + _userLogic = userLogic; + } + + [HttpGet] + [HttpPost] + public IActionResult Login(LoginModel model) + { + var errors = new List(); + if (HttpContext.Request.Method == "POST") + { + var user = _userLogic.ReadElement(new UserSearchModel { Email = model.Email, Password = model.Password }); + if (user == null) + { + errors.Add("Неверные логин или пароль"); + } + else if (user.Role != UserRole.Исполнитель) + { + errors.Add("Пользователь имеет неразрешенную роль"); + } + if (errors.Count > 0) + { + model = new LoginModel + { + Errors = errors + }; + return View(model); + } + LoginManager.LogginedUser = user; + return RedirectToAction("", "Home"); + } + else + { + model = new(); + return View(model); + } + } + + [HttpGet] + [HttpPost] + public IActionResult Register(RegisterModel model) + { + var errors = new List(); + if (HttpContext.Request.Method == "POST") + { + if (_userLogic.ReadElement(new UserSearchModel { Email = model.Email }) != null) + { + errors.Add("Пользователь с таким Email уже есть"); + } + if (model.Password != model.ConfirmPassword) + { + errors.Add("Пароли не совпадают"); + } + if (errors.Count > 0) + { + model.Errors = errors; + model.Password = string.Empty; + model.ConfirmPassword = string.Empty; + return View(model); + } + var user = new UserBindingModel + { + FIO = model.FIO, + Email = model.Email, + Password = model.Password, + Role = UserRole.Исполнитель + }; + _userLogic.Create(user); + return RedirectToAction("Login"); + } + else + { + return View(model); + } + } + + [HttpPost] + public IActionResult Logout() + { + LoginManager.LogginedUser = null; + return RedirectToAction("Login"); + } + } +} diff --git a/Polyclinic/PolyclinicWebAppImplementer/LoginManager.cs b/Polyclinic/PolyclinicWebAppImplementer/LoginManager.cs new file mode 100644 index 0000000..7b6a301 --- /dev/null +++ b/Polyclinic/PolyclinicWebAppImplementer/LoginManager.cs @@ -0,0 +1,9 @@ +using PolyclinicContracts.ViewModels; + +namespace PolyclinicWebAppImplementer +{ + public static class LoginManager + { + public static UserViewModel? LogginedUser { get; set; } + } +} diff --git a/Polyclinic/PolyclinicWebAppImplementer/Models/LoginModel.cs b/Polyclinic/PolyclinicWebAppImplementer/Models/LoginModel.cs new file mode 100644 index 0000000..268f137 --- /dev/null +++ b/Polyclinic/PolyclinicWebAppImplementer/Models/LoginModel.cs @@ -0,0 +1,9 @@ +namespace PolyclinicWebAppImplementer.Models +{ + public class LoginModel + { + public string Email { get; set; } = string.Empty; + public string Password { get; set; } = string.Empty; + public List Errors { get; set; } = new(); + } +} diff --git a/Polyclinic/PolyclinicWebAppImplementer/Models/RegisterModel.cs b/Polyclinic/PolyclinicWebAppImplementer/Models/RegisterModel.cs new file mode 100644 index 0000000..b2c4ac1 --- /dev/null +++ b/Polyclinic/PolyclinicWebAppImplementer/Models/RegisterModel.cs @@ -0,0 +1,11 @@ +namespace PolyclinicWebAppImplementer.Models +{ + public class RegisterModel + { + public string FIO { get; set; } = string.Empty; + public string Email { get; set; } = string.Empty; + public string Password { get; set; } = string.Empty; + public string ConfirmPassword { get; set; } = string.Empty; + public List Errors = new(); + } +} diff --git a/Polyclinic/PolyclinicWebAppImplementer/PolyclinicWebAppImplementer.csproj b/Polyclinic/PolyclinicWebAppImplementer/PolyclinicWebAppImplementer.csproj index f097bc6..bc275c0 100644 --- a/Polyclinic/PolyclinicWebAppImplementer/PolyclinicWebAppImplementer.csproj +++ b/Polyclinic/PolyclinicWebAppImplementer/PolyclinicWebAppImplementer.csproj @@ -1,4 +1,4 @@ - + net6.0 @@ -18,7 +18,7 @@ true PreserveNewest - + true PreserveNewest diff --git a/Polyclinic/PolyclinicWebAppImplementer/Program.cs b/Polyclinic/PolyclinicWebAppImplementer/Program.cs index ed8ed4f..ad50cb6 100644 --- a/Polyclinic/PolyclinicWebAppImplementer/Program.cs +++ b/Polyclinic/PolyclinicWebAppImplementer/Program.cs @@ -17,6 +17,9 @@ builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); +builder.Services.AddTransient(); +builder.Services.AddTransient(); + builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); diff --git a/Polyclinic/PolyclinicWebAppImplementer/RestrictionEnum.cs b/Polyclinic/PolyclinicWebAppImplementer/RestrictionEnum.cs new file mode 100644 index 0000000..bfc2b92 --- /dev/null +++ b/Polyclinic/PolyclinicWebAppImplementer/RestrictionEnum.cs @@ -0,0 +1,9 @@ +namespace PolyclinicWebAppImplementer +{ + public enum PageVisible + { + AllowAnyBody = 0, + AllowOnlyAuthorized = 1, + AllowOnlyNotAuthorized = 2, + } +} diff --git a/Polyclinic/PolyclinicWebAppImplementer/SiteMenuItems.cs b/Polyclinic/PolyclinicWebAppImplementer/SiteMenuItems.cs index 393e79d..70b305a 100644 --- a/Polyclinic/PolyclinicWebAppImplementer/SiteMenuItems.cs +++ b/Polyclinic/PolyclinicWebAppImplementer/SiteMenuItems.cs @@ -2,18 +2,18 @@ { public static class SiteMenuItems { - public static (string Controller, string Action, string Title) Index = ("Home", "", "Главная"); - public static (string Controller, string Action, string Title) Courses = ("Courses", "", "Курсы"); - public static (string Controller, string Action, string Title) Diagnoses = ("Diagnoses", "", "Болезни"); - public static (string Controller, string Action, string Title) Symptomes = ("Symptomes", "", "Симптомы"); - public static (string Controller, string Action, string Title) Login = ("Home", "Login", "Вход"); - public static (string Controller, string Action, string Title) Register = ("Home", "Register", "Регистрация"); - public static (string Controller, string Action, string Title) Privacy = ("Home", "Privacy", "Политика приватности"); - public static (string Controller, string Action, string Title) AddRecipeToCourse = ("Home", "AddRecipeToCourse", "Привязка рецепта"); - public static (string Controller, string Action, string Title) MedicamentsByDiagnoses = ("Home", "MedicamentsByDiagnoses", "Лекарства по болезням"); - public static (string Controller, string Action, string Title) DiagnosesReport = ("Home", "DiagnosesReport", "Отчет по болезням"); + public static (string Controller, string Action, string Title, PageVisible Visible) Index = ("Home", "", "Главная", PageVisible.AllowAnyBody); + public static (string Controller, string Action, string Title, PageVisible Visible) Courses = ("Courses", "", "Курсы", PageVisible.AllowOnlyAuthorized); + public static (string Controller, string Action, string Title, PageVisible Visible) Diagnoses = ("Diagnoses", "", "Болезни", PageVisible.AllowOnlyAuthorized); + public static (string Controller, string Action, string Title, PageVisible Visible) Symptomes = ("Symptomes", "", "Симптомы", PageVisible.AllowOnlyAuthorized); + public static (string Controller, string Action, string Title, PageVisible Visible) Login = ("User", "Login", "Вход", PageVisible.AllowOnlyNotAuthorized); + public static (string Controller, string Action, string Title, PageVisible Visible) Register = ("User", "Register", "Регистрация", PageVisible.AllowOnlyNotAuthorized); + public static (string Controller, string Action, string Title, PageVisible Visible) Privacy = ("Home", "Privacy", "Политика приватности", PageVisible.AllowAnyBody); + public static (string Controller, string Action, string Title, PageVisible Visible) AddRecipeToCourse = ("Home", "AddRecipeToCourse", "Привязка рецепта", PageVisible.AllowOnlyAuthorized); + public static (string Controller, string Action, string Title, PageVisible Visible) MedicamentsByDiagnoses = ("Home", "MedicamentsByDiagnoses", "Лекарства по болезням", PageVisible.AllowOnlyAuthorized); + public static (string Controller, string Action, string Title, PageVisible Visible) DiagnosesReport = ("Home", "DiagnosesReport", "Отчет по болезням", PageVisible.AllowOnlyAuthorized); - public static List<(string Controller, string Action, string Title)> MenuItemsOrder = new List<(string Controller, string Action, string Title)> + public static List<(string Controller, string Action, string Title, PageVisible Visible)> MenuItemsOrder = new List<(string Controller, string Action, string Title, PageVisible Visible)> { Index, Courses, Diagnoses, Symptomes, Login, Register, AddRecipeToCourse, MedicamentsByDiagnoses, DiagnosesReport }; diff --git a/Polyclinic/PolyclinicWebAppImplementer/Views/Shared/_Layout.cshtml b/Polyclinic/PolyclinicWebAppImplementer/Views/Shared/_Layout.cshtml index 75744fe..fa8f255 100644 --- a/Polyclinic/PolyclinicWebAppImplementer/Views/Shared/_Layout.cshtml +++ b/Polyclinic/PolyclinicWebAppImplementer/Views/Shared/_Layout.cshtml @@ -32,19 +32,30 @@ + @if(LoginManager.LogginedUser != null) + { +
+ +
+ } diff --git a/Polyclinic/PolyclinicWebAppImplementer/Views/Home/Login.cshtml b/Polyclinic/PolyclinicWebAppImplementer/Views/User/Login.cshtml similarity index 61% rename from Polyclinic/PolyclinicWebAppImplementer/Views/Home/Login.cshtml rename to Polyclinic/PolyclinicWebAppImplementer/Views/User/Login.cshtml index 4855fc6..a61a489 100644 --- a/Polyclinic/PolyclinicWebAppImplementer/Views/Home/Login.cshtml +++ b/Polyclinic/PolyclinicWebAppImplementer/Views/User/Login.cshtml @@ -1,20 +1,27 @@ -@{ +@model LoginModel +@{ ViewBag.SelectedSiteMenuItem = SiteMenuItems.Login; }

Вход

+ @foreach (var item in Model.Errors) + { + + }
- +
- +