【问题标题】:What is the most standard way to persist data between MVC views?在 MVC 视图之间保存数据的最标准方法是什么?
【发布时间】:2014-05-11 21:12:51
【问题描述】:

我正在创建一个使用 ASP.NET MVC 填写在线工作申请的系统。这实际上只是一个让自己熟悉 MVC 框架的实验。我绝对不是安全专家,所以我只是想在这里得到一些建议,因为这个网络应用程序将处理敏感信息。

系统有一组类似向导的视图。您从一个视图到下一个视图填写相关信息,直到最后提交。

每个工作申请都使用 GUID 主键存储在数据库中。现在,我只是将该 GUID 存储在每个页面视图中的隐藏字段中。这使得更新控制器中的模型变得很容易,如下所示:

[HttpPost]
public ActionResult ExampleAction(FormCollection formValues)
{
    Guid appId = new Guid(Request.Form["ModelId"]); // the GUID stored in the hidden field
    ExampleModel example = db.Entities.Single(e => e.ModelId == appId);

    UpdateModel(example, formValues);
    db.SaveChanges();

    return RedirectToAction("ExampleAction2", new { appId = appId.ToString() });
}

我知道这并不安全,因为任何具有任何开发经验的人都知道您可以在任何浏览器的开发人员工具中编辑隐藏字段的值。那么,安全获得相同结果的推荐方法是什么?

【问题讨论】:

  • 他们当然可以编辑该字段。如果他们将其编辑为无效的内容,只需扔掉该应用程序。如果他们将其编辑为有效的内容,那么他​​们是如何访问其他人的 GUID 的?
  • 您只想保留 GUID? MVC 的关键特性之一是路由和详细 URL。这意味着,如果显示 ID 没有问题,请在 URL 上加上 jobs/view/GUIDjobs/apply/GUID。否则,我会在会议上保留它
  • @Brandon 我不担心他们劫持另一个应用程序——这几乎是不可能的。只是对向用户隐藏实现细节感兴趣。

标签: c# asp.net-mvc asp.net-mvc-3 security


【解决方案1】:

您应该将它存储在 Session 对象中。这样,您可以随时随地调用它,并且它永远不会显示在您的任何视图上。 文档:http://msdn.microsoft.com/en-us/library/ms178581.aspx

【讨论】:

  • 更进一步,我会将其封装在一个接口中,以便您以后可以轻松地对其进行模拟和单元测试。
  • Sessions 在云环境中是邪恶的,因为它们是按服务器创建的,并且在云托管中,我们永远不知道哪个服务器正在处理请求,并且只有一页可以从一台服务器提供服务,而下一台则从另一台服务器提供...您将丢失所有内容...在 .NET 中使用缓存层,例如 MemCached。
  • @balexandre re:“每台服务器创建”——谁说的?您可以根据msdn.microsoft.com/en-us/library/ms178586%28v=vs.100%29.aspx 轻松使用StateServerSQLServer 模式(甚至Custom
【解决方案2】:

我知道这已经得到回答,只是为了兴趣,我想留下另一个选择。您可以如何处理它,将从第一个视图中获得的信息解析为 JSON 字符串,您可以将其存储在 cookie 中,然后在需要时对其进行序列化。

这是假设信息可以安全地存储在客户端。否则我想它可能是一个加密的cookie。这将解决云计算和负载均衡器等问题。

【讨论】:

    【解决方案3】:

    为什么不发布到每个步骤而不是使用 RedirectToAction?这样您就可以创建一个包含每个步骤的模型。例如:

    class JobApplicationViewModel
    {
        public Guid ApplicationGuid { get; set; }
        public StepOne Step1 { get; set; }
        public StepTwo Step2 { get; set; }
        public int CurrentStep { get; set; }
    }
    

    第 1 步的视图可以发布到第 2 步。例如:

    [HttpPost]
    public ViewResult StepTwo(JobApplicationViewModel viewModel)
    {
        ServiceLayer.Update(viewModel);
        return View(viewModel);
    }
    

    然后,StepTwo 视图发布到 StepThree,StepThree 发布到 Step4,等等。这在逻辑上是有道理的,因为您只允许人们通过发布表单进入步骤 1 之外的任何步骤。

    【讨论】:

    • 它工作得很好,但这不是最好的可维护性,是吗?我认为表单应该发布到他们自己的操作中以提高可读性。例如,没有人愿意记住“ContactInfo”表单发布到“CareerExperience”操作。
    • 虽然这是一个有效的论点.. 如果过程是 StepOne -> StepTwo -> StepThree.. 这有点不同。我假设您将整个过程描述为步骤,而不是步骤的描述,在这种情况下,我不会使用我的建议。
    猜你喜欢
    • 1970-01-01
    • 2011-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-23
    • 1970-01-01
    • 1970-01-01
    • 2018-06-16
    相关资源
    最近更新 更多