Предотвращение подделки полей формы в ASP.NET MVC EF

Строго типизированная страница редактирования по умолчанию в ASP.NET MVC 3 обычно предоставляет все поля для сущности. Хотя это часто работает, некоторые поля представляют угрозу безопасности. Например, упрощенная сущность подписки на журнал может выглядеть следующим образом:

public void Subscription() {
  public int Id { get; set; }
  public string Name { get; set; }
  public string Address { get; set; }
  public string City { get; set; }
  public string State { get; set; }
  public string Zip { get; set; }
  public DateTime SubscribedThru { get; set; }
}

Если я предоставлю страницу редактирования, чтобы пользователи могли изменить свой собственный адрес, например, включение поля SubscribedThruпредставляет угрозу безопасности, поскольку Злоумышленник может дать себе бесплатную 10-летнюю подписку, подделав дату (даже если я использую @Html.HiddenFor(model => model.SubscribedThru).Поэтому я никак не включаю это поле в html страницы редактирования (через бритву).

Я думал, что ответ может состоять в том, чтобы предотвратить попытки привязки SubscribedThruк методу Edit в контроллере, используя что-то вроде:

[HttpPost]
public ActionResult Edit([Bind(Exclude="SubscribedThru")] Subscription subscription) {
  if (ModelState.IsValid) {
    db.Entry(subscription).State = EntityState.Modified;
    db.SaveChanges();
    return RedirectToAction("Index");
    }
  }
  return View(subscription);
}

Когда я доберусь до SaveChanges();строка выдает ошибку Преобразование типа данных datetime2 в тип данных datetime привело к значению вне допустимого диапазона. Я считаю, что дата SubscribedThru (правильно?) не существует, а пустое значение меньше, чем может обработать SQL Server. Что меня удивляет, так это то, что он даже пытается обновить это поле, когда для него исключен Binding.

На данный момент моим лучшим решением кажется создание пользовательской ViewModel, в которой отсутствует дата SubscribedThru, но это кажется большим дублированием полей, валидацией и т. д.; если возможно, я хотел бы просто сделать одно поле SubscribedThruбезопасным для редактирования пользователем.

Я не могу сказать, что полностью понимаю методы UpdateModelи TryUpdateModelи задаюсь вопросом, можно ли двигаться дальше? Я играл с ними, и EF выдает ошибки из-за дублирования объектов (одного и того же ключа), что вызывает недоумение.

Кроме того, мне непонятно, сохраняются ли данные подписки от начальной загрузки в public ActionResult Edit(int id)в контроллере вплоть до окончательного [HttpPost] общедоступный метод ActionResult Edit(Подписка на подписку)... или строка db.Entry(subscription).State = EntityState.Изменено; попробуйте установить все данные (я думал, что это просто установка флага, указывающего «отредактировано, поэтому EF должен сохранить это»).

Я давний разработчик .NET, только приступаю к своему первому проекту ASP.NET MVC, поэтому, вероятно, упускаю из виду что-то до боли очевидное. Спасибо за любую помощь!

5
задан Larry S 12 June 2012 в 15:34
поделиться