Каковы обязанности компонентов в шаблоне MVC для простого входа
Я пытаюсь понять шаблон MVC, и я получаю общее представление о том, что Модель отвечает за поддержание состояния, Представление отвечает за отображение Модели, а Контроллер отвечает за изменение Модели и вызывает соответствующие Представления., Я хотел попробовать и реализовать простую страницу входа ASP.NET MVC, которая использует OpenID, чтобы получить некоторое представление о том, как все это работает.
Я скачал DotNetOpenAuth-3.4.6 и просматривал примеры, в частности их образец MVC. К сожалению, образец на самом деле не имеет модели, только контроллер:
namespace OpenIdRelyingPartyMvc.Controllers
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OpenId;
using DotNetOpenAuth.OpenId.RelyingParty;
public class UserController : Controller
{
private static OpenIdRelyingParty openid = new OpenIdRelyingParty();
public ActionResult Index()
{
if (!User.Identity.IsAuthenticated)
{
Response.Redirect("~/User/Login?ReturnUrl=Index");
}
return View("Index");
}
public ActionResult Logout()
{
FormsAuthentication.SignOut();
return Redirect("~/Home");
}
public ActionResult Login()
{
// Stage 1: display login form to user
return View("Login");
}
[ValidateInput(false)]
public ActionResult Authenticate(string returnUrl)
{
var response = openid.GetResponse();
if (response == null)
{
// Stage 2: user submitting Identifier
Identifier id;
if (Identifier.TryParse(Request.Form["openid_identifier"], out id))
{
try
{
return openid.CreateRequest(Request.Form["openid_identifier"]).RedirectingResponse.AsActionResult();
}
catch (ProtocolException ex)
{
ViewData["Message"] = ex.Message;
return View("Login");
}
}
else
{
ViewData["Message"] = "Invalid identifier";
return View("Login");
}
}
else
{
// Stage 3: OpenID Provider sending assertion response
switch (response.Status)
{
case AuthenticationStatus.Authenticated:
Session["FriendlyIdentifier"] = response.FriendlyIdentifierForDisplay;
FormsAuthentication.SetAuthCookie(response.ClaimedIdentifier, false);
if (!string.IsNullOrEmpty(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
case AuthenticationStatus.Canceled:
ViewData["Message"] = "Canceled at provider";
return View("Login");
case AuthenticationStatus.Failed:
ViewData["Message"] = response.Exception.Message;
return View("Login");
}
}
return new EmptyResult();
}
}
}
Возможно, образец слишком прост, чтобы задействовать модель, так как вся информация о состоянии содержится в Cookie. Впоследствии я реализовал простую базу данных, которая имеет одну таблицу Users:
Users
+ user_id
+ open_id
+ last_login
Я предполагаю, что мне понадобится LoginModel
:
public class LogInModel
{
[Required]
[DisplayName("OpenID")]
public string OpenID { get; set; }
}
DisplayModel
:
public class DisplayModel
{
[DisplayName("User ID")]
public string UserID{ get; set; }
[DisplayName("OpenID")]
public string OpenID { get; set; }
[DisplayName("Last Login")]
public DateTime LastLogin{ get; set; }
}
Кроме того, мне может понадобиться ModifyModel
, но DisplayModel
может быть повторно использован и, возможно, переименован в UserModel
(чтобы правильно отразить использование модели).
Итак, теперь у меня есть несколько вопросов:
- Отвечает ли контроллер за проверку ввода пользователя или это делается, когда ввод передается в модель (т.е.
Identifier.TryParse
наopenid_identifier
)? - Я хочу разрешить пользователю вход в систему, изменить его информацию (например, user_id) и просмотреть их информацию (например, user_id, open_id и last_login). Сколько моделей мне нужно (
ModifyModel
,DisplayModel
а такжеLogInModel
)? - Какова продолжительность жизни модели? Модель существует где-то статически или просто создана контроллером и передана в представление?
- Было бы лучше добавить базу данных в качестве модели, а не делать вышеупомянутые модели?
1 ответ
1) Это может быть да, но лучшим подходом было бы использование аннотаций данных в ViewModel.
2) Подойдет одна модель. Модель должна представлять общий объект, в данном случае "Пользователь". Если информация, необходимая для каждого просмотра, сильно отличается, то разделите их на модели просмотра.
3) Не уверен, что вы имеете в виду. MVC (и ASP.NET в целом) основаны на протоколе HTTP и поэтому не сохраняют состояния. Поэтому, когда вы нажимаете URL, назначается контроллер, а затем объекты обновляются, как того требует код - это включает соединение с базой данных. Затем, когда запрос завершен, все пропало (все равно управляемые ресурсы). Постарайтесь не запутаться со словом "модель". Это не физическая сущность, а область вашей модели программирования.
4) Как правило, вашей "моделью" является ваш репозиторий /DAL/ORM, который оборачивает вашу базовую базу данных и представляет модель вашего домена. Ваше мнение не должно касаться домена. Это работа вашего контроллера / модели. Ваш вид должен работать с тем, что ему нужно, и не более. Вот почему, как правило, никогда не привязывайте напрямую к модели ORM, используйте ViewModel.
Изменить - в ответ на вопросы в комментариях:
Извините... для 1 аннотации данных предполагают, что проверка выполняется на модели, но OpenId.Identifier также предоставляет некоторые функции, которые могут проверять ввод (например, TryParse), так что было бы более согласованным делать всю проверку на модели или "место" проверки обычно не так строго?
Поместите аннотации данных в ViewModel, которые являются представлениями модели, созданной для облегчения представления. Аннотации данных не должны быть наложены на ваши сущности модели (Entity Framework, L2SQL и т. Д.). Аннотации данных должны использоваться для проверки ввода (сравнение пароля, длины символов, телефонных номеров, адресов электронной почты и т. Д.). Проверка бизнеса должна проводиться в домене. Я бы сказал, что OpenId - это сервис, а не часть домена. Если у них есть некоторые функции проверки, вы можете обернуть эти вызовы в пользовательские аннотации данных и поместить их в свою модель представления. Это был бы чистый и последовательный подход.
В отношении 3 я согласен с тем, что протокол HTTP не имеет состояния, но если я правильно понимаю, файлы cookie являются одним из способов поддержания состояния, и модель предоставляет альтернативный способ.
Ваше право, куки являются одним из способов поддержания состояния. Для этого обычно используется билет проверки подлинности с помощью форм. Еще одна сессия. TempData использует Session (по-умному - автоматический выброс). Модель не является "альтернативным способом" - она не поддерживает состояние. Подробнее об этом поговорим ниже.
В прикладном программировании состояние (т. Е. Объект) обычно является постоянным в течение всего жизненного цикла приложения, поэтому, если бы я создал модель в консольном приложении, он существовал бы до тех пор, пока на него есть ссылка. Поэтому, когда вы говорите, что "объекты являются новыми", это означает, что объект Model уже создан (как в консольном приложении), и я просто "обновляю" его, или это означает, что я создаю новую модель?
В консольном приложении - ваше право. Пока консольное приложение работает, объекты живы. Но в веб-приложении ASP.NET MVC "родителем" является рабочий поток ASP.NET, назначаемый при поступлении запроса. Все необходимые объекты (контроллер, соединение с базой данных, хранилище, объекты домена) являются "потомками" этот поток, если это имеет смысл. Как только этот поток исчезнет, исчезнут все связанные объекты.
Опять же, нет "волшебного воплощения" модели - Модель - это общее представление / представление вашего домена, которое обычно состоит из модели домена (сущности, бизнес-логика) и хранилища.
Единственным исключением является "привязка к модели". Когда вы отправляете форму на [HttpPost]
действие, строго типизированное для "модели" (должно быть ViewModel). ASP.NET MVC (через отражение) построит эту "модель" на основе полей в HTTP POST.
Когда вы делаете что-то вроде "UpdateModel", все, что вы делаете, это обновляет объект, который вы предоставляете, тем, что поступило в метод действия через привязку модели. Фактическая база данных не обновляется.
Не знаю, что еще я могу сказать. Похоже, у вас возникает путаница по поводу "модели". Могу ли я предложить вам взять книгу Стивена Сандерсона Pro ASP.NET MVC 2 Framework. Это фантастика, объясняет все с нуля - простыми словами, затем наращивает темп, чтобы стать экспертом к концу книги.