【问题标题】:MVC 4 FormCollection not updated on resubmit重新提交时未更新 MVC 4 FormCollection
【发布时间】:2013-10-07 16:03:39
【问题描述】:

以下是我的问题的事实:

  1. 我在 ASP.Net MVC 4 Web 应用程序中有一个表单。
  2. 表单上的字段与模型中的显式静态属性无关。相反,它们是可以更改的动态字段。
  3. 提交表单后,我使用 FormcCollection 检索输入到字段值中的值。
  4. 我第一次提交表单时,一切正常:FormCollection 的值准确地反映了表单值。
  5. 如果由于一个或多个无效字段导致字段值出现问题,我会重新显示表单。
  6. 如果用户更改表单的值以更正验证错误,然后重新提交相同的表单,FormCollection 不会更新以反映最新的表单值。相反,它始终包含第一次提交的字段值。

为什么会发生这种情况,我该如何纠正?

<HttpPost()> _
<HttpParamAction()> _
Function Upload(ByVal model As MaxDocument, formcollection As FormCollection) As ActionResult
  Dim sCriteria As String = ""
  Dim nKeyIndex As Integer = 0
  Dim nFieldIndex As Integer = -1
  Dim sFieldValue As String = ""

  Try
    ' Build sCriteria from the submitted formcollection
    model.GetFileCabinetFieldList()
    For nFieldIndex = 0 To (model.IndexFieldCount - 1)
      sFieldValue = ""
      If nFieldIndex > 0 Then
        sCriteria += "~"
      End If
      Dim fcf As MaxServerLib.FileCabinetField = model.criterionAtIndex(nFieldIndex)
        ' Get the field value corresponding to this field
        For Each oKey As Object In formcollection.AllKeys
          If oKey.ToString = fcf.sFieldName Then
            sFieldValue = formcollection(oKey.ToString)
            Exit For
          End If
        Next
        sCriteria += sFieldValue
      Next
      If sCriteria = "" Then sCriteria = "[BlankIndex]"

      ' Set the criteria property of the model, which will be used for both field validation and document export.
      model.Criteria = sCriteria

      ' First thing we do is to perform valiation of the criteria
      model.ValidateFieldValues()
      If Not model.AllFieldValuesValid() Then
        ' Handle case where one or more field values are invalid.
        ' In this case we want to redisplay the form but show an error message listing the invalid fields

        model.HasAttemptedUpload = True
        ' Set tempData before redirect:
        TempData("MaxDocument") = model
        Return RedirectToAction("Index")
      Else
        ' All field values are valid, now attempt to add the document
    ...
      End If

    Catch ex As Exception
      System.Diagnostics.Debugger.Break()
    End Try
  'End If

  ' If we got this far, something failed, redisplay form
  Return View(model)

End Function

编辑:

似乎正在发生的事情是浏览器已经缓存了第一个帖子的帖子操作,并且在每个后续帖子(第一个帖子之后)它呈现第一个帖子的缓存结果而不是呈现当前帖子的结果.为什么要这样做?

【问题讨论】:

  • 在您的 POST 操作中,您是否修改了其中一些值?你能展示你的代码吗?
  • 看看这个问题,旧数据处于模型状态,在新提交时没有更新。 stackoverflow.com/questions/7414351/…
  • 上面显示的 POST 操作中的重要代码。
  • Marko,这是一个有趣的话题。真正的问题可能不是 FormCollection,而是视图中的表单字段错误地返回缓存值而不是最后输入的值?
  • Dimitri,我在这里看到了您的帖子stackoverflow.com/questions/7414351/…,我想澄清一下,在我的情况下,我没有修改控制器中的发布值。所有修改都发生在表单视图中,但我怀疑模型状态是我问题的罪魁祸首。

标签: asp.net-mvc forms


【解决方案1】:

我创建了一个类NoCacheControlAttribute

NoCacheControlAttribute.cs:

using System;
using System.Web;
using System.Web.Mvc;
namespace Company.Common.Web.MVC
{
    public class NoCacheControlAttribute : ActionFilterAttribute
    {
        private readonly HttpCacheability _cacheability;
        public NoCacheControlAttribute(HttpCacheability cacheability)
        {
            _cacheability = cacheability;
        }
        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            HttpCachePolicyBase cache = filterContext.HttpContext.Response.Cache;
            cache.SetAllowResponseInBrowserHistory(false);
            cache.SetCacheability(_cacheability);
            cache.SetExpires(DateTime.Now);
            cache.SetNoServerCaching();
            cache.SetNoStore();
        }
    }
}

我通过 Autofac Dependency Injection / Constructor Injection 获得了可缓存性参数。

...Controller.cs

using ...
using System.Web;
using System.Web.Mvc;
using Company.Common.Web.MVC;
using ...
namespace Company.Project.Web.Controllers
{
    [NoCacheControl(HttpCacheability.NoCache)]
    public class ContractController : Controller
    {
        private readonly IRepository _repository;
        public ContractController(IRepository repository)
        {
            _repository = repository;
        }
        [HttpGet]
        public ActionResult ActionTest(string id)
        {
            ...
            return ...;
        }
    }
}

因此,缓存被禁用!

【讨论】:

  • 感谢您的努力 Florian,但遗憾的是您的解决方案未能解决问题。我的问题中涉及的缓存似乎是浏览器缓存,而不是服务器端缓存。浏览器似乎已经缓存了第一个帖子的结果,因此所有后续帖子都使用这些结果而不是当前帖子结果。
猜你喜欢
  • 2022-12-30
  • 2013-10-07
  • 2015-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-25
  • 2019-01-23
相关资源
最近更新 更多