Я использую шаблон post-redirect-get (PRG) для сохранения сущности в ASP.Net MVC 2. Методами контроллера являются «Сохранить» (вставить или обновить базу данных) и «Редактировать» (получить ввод пользователя). В «Сохранить» я проверяю изменения перед сохранением, проверяя столбец «версия» сущности. Если кто-то изменил объект, столбец «version» не будет совпадать, и я отправлю пользователю сообщение об ошибке.
Для поддержки сообщений об ошибках я использую ModelState.Merge в методе «Edit». Проблема с этим механизмом состоит в том, что пользовательский ввод сохраняется, и пользователь не видит изменения, сделанные другим пользователем. Я избегаю этой проблемы, очищая ModelState перед добавлением сообщения о конфликте параллелизма.
Но я чувствую, что это решение не оптимально. Как бы вы справились с конфликтом параллелизма в ASP.Net MVC?
Вот метод редактирования:
Public Function Edit() As ActionResult
Dim theevent As AEvents
If TempData("ModelState") IsNot Nothing And Not ModelState.Equals(TempData("ModelState")) Then
ModelState.Merge(CType(TempData("ModelState"), ModelStateDictionary))
End If
If RouteData.Values.ContainsKey("id") Then
theevent = NHibGet.EventWithPricingsByCode(RouteData.Values("id"))
Else
theevent = New AEvents
End If
Dim InputTemplate As New EventEdit With {.EventDate = theevent.EventDate, .EventName = theevent.EventName, .IsActive = theevent.IsActive}
If theevent.Template IsNot Nothing Then
InputTemplate.TemplateID = theevent.Template.ID
End If
Dim templates As IList(Of SeatTemplates) = NHibGet.TemplatesActive
ViewData("templates") = templates
ViewData("eventcode") = theevent.Code
ViewData("editversion") = theevent.Version
Return View(InputTemplate)
End Function
А код для «Сохранить» выглядит так:
Public Function Save(ByVal id As Integer, ByVal UserData As EventEdit, ByVal EditVersion As Integer) As ActionResult
Dim theevent As AEvents
If id = 0 Then
theevent = New AEvents
Else
theevent = NHibGet.EventByCode(id)
End If
If theevent.Version <> EditVersion Then
ModelState.Clear()
ModelState.AddModelError("", "The event is modified by someone else")
Return RedirectToAction("Edit", New With {.id = id})
End If
If Not ModelState.IsValid Then
TempData("ModelState") = ModelState
Return RedirectToAction("Edit", New With {.id = id})
End If
theevent.EventDate = UserData.EventDate
theevent.EventName = UserData.EventName
theevent.IsActive = UserData.IsActive
theevent.Template = MvcApplication.CurrentSession.Load(Of SeatTemplates)(UserData.TemplateID)
Using trans As NHibernate.ITransaction = MvcApplication.CurrentSession.BeginTransaction
MvcApplication.CurrentSession.SaveOrUpdate(theevent)
Try
trans.Commit()
Catch ex As NHibernate.ADOException
trans.Rollback()
Throw ex
End Try
End Using
Return RedirectToAction("Edit", New With {.id = theevent.Code})
End Function