【问题标题】:How to handle concurrency clash in ASP.Net MVC using post-redirect-get?如何使用 post-redirect-get 处理 ASP.Net MVC 中的并发冲突?
【发布时间】:2010-10-18 08:01:31
【问题描述】:

我使用后重定向获取 (PRG) 模式在 ASP.Net MVC 2 中保存实体。控制器方法是“保存”(插入或更新数据库)和“编辑”(检索用户输入)。在“保存”中,我在保存之前通过检查实体的“版本”列进行修改检查。如果其他人修改了实体,“版本”列将不匹配,我将向用户发送错误消息。

为了维护错误消息,我在“编辑”方法中使用了 ModelState.Merge。这种机制的问题是用户输入被维护并且用户看不到其他用户所做的修改。我通过在添加并发冲突消息之前清除 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

【问题讨论】:

  • 感觉这根本不是 ASP.NET MVC 特定的。您需要锁定项目以进行编辑,或者您需要在保存时允许合并项目,或者您需要在保存时覆盖项目。听起来合并选项就是您想要的。在尝试保存旧版本以允许当前用户手动合并每个字段时,也许您可​​以以只读格式呈现当前用户现在已过时的编辑?
  • 我会说我的问题是特定于 MVC 的,因为如果有人用 PHP 举例,它可能无法翻译成 MVC。不过谢谢你的回答。

标签: asp.net-mvc concurrency post-redirect-get


【解决方案1】:

我总是在这种情况下指示用户刷新页面。这也让他有机会查看输入的字段值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-29
    • 2011-05-24
    • 1970-01-01
    • 1970-01-01
    • 2012-07-26
    • 1970-01-01
    相关资源
    最近更新 更多