【问题标题】:Storing state in asp.net MVC在 asp.net MVC 中存储状态
【发布时间】:2009-12-31 09:36:15
【问题描述】:

我正在构建一个 asp.net MVC 2 应用程序。

我有一个列表视图,它根据参数列出项目。在数据库中,我有一个父子表,因此我的列表视图列出了父 ID 与参数中指定的值匹配的所有子记录。

这是我的控制器和模型:

public ActionResult List(int ParentID)
{
    return View(new Models.ChildListModel(ParentID));
}

public class ChildListModel
{
    public int ParentID {get;set;}

    public ManagementUserListModel(int iParentID)
    {
        this.ParentID = iParentID;
        this.Children = DataAccessLayer.ListChildrenForParent(iParentID);
    }

    public List<Child> Children {get;set;}
}

我还有一个详细信息并为该控制器创建操作。详细信息和创建视图有一个“返回列表”操作,我想返回到列表视图,并保持原来的 ParentID。到目前为止,我一直在通过在列表、编辑、创建和详细信息视图中创建一个名为 ParentID 的隐藏字段来执行此操作,以便正确填充模型的 ParentID 属性:

<%= Html.HiddenFor(model => model.ParentID) %>

然后在每个视图的“返回列表”操作中,我传递 ParentID:

<%=Html.ActionLink("Back to List", "List", new {ParentID = Model.ParentID}) %>

这一切都有效,但我不喜欢在 html 中存储原始 ID。有没有更好的方法来做到这一点?是否有一些内置方法来加密数据(有点像标准的 asp.net 视图状态?)我只是想实现某种防篡改,并试图避免使用会话状态(TempData 等),因为我不想处理会话超时。

【问题讨论】:

  • ViewState 是 base64 编码的,很容易“解密”。我想问题是,为什么不使用原始的商店 ID?它有什么问题?

标签: asp.net-mvc asp.net-mvc-2


【解决方案1】:

你可以看看这个article。您可以在视图中使用新的 Html.Serialize 扩展方法,它允许您序列化整个对象并对其进行加密:

<%= Html.Serialize("person", Model, SerializationMode.Encrypted) %>

它将模型序列化为隐藏字段并加密值。要取回模型,请在表单提交到的控制器操作中使用 DeserializeAttribute

public ActionResult Edit([Deserialize]Person person)  { }

【讨论】:

    【解决方案2】:

    另一种不暴露 id 并且不增加后续表单发布的权重的方法(如 Webform 的 ViewState 和 Html.Serialize 会)是使用会话作为内部的后备存储你的模型类。

    public class ChildListModel
    {
        public int ParentID {
            get
            {
                return (int)HttpContext.Current.Session["ChildListModel.ParentID"];
            }
            set
            {
                HttpContext.Current.Session["ChildListModel.ParentID"] = value;
            }
        }
    
        public ManagementUserListModel(int iParentID)
        {
            this.ParentID = iParentID;
            this.Children = DataAccessLayer.ListChildrenForParent(iParentID);
        }
    
        public List<Child> Children {get;set;}
    }
    

    如果您愿意,您甚至可以将整个 Parent 对象存储在您的模型中,而不仅仅是它的 ID - 这会增加服务器上的会话大小,这可能是可取的,也可能是不可取的(取决于您的会话多长时间lasts 以及是否设置为存储在内存中还是存储在 sql server 中等)

    【讨论】:

    • 哎呀,在最初的问题结束时没有看到“并试图避免使用会话状态”。我仍然认为以上内容可能对某些阅读此主题的人有用,因此我将保留它。
    【解决方案3】:

    最简单的方法是在 URL 中保留 parentid。 Create Action 看起来有点奇怪,但我仍然认为这是不太麻烦的方式。

    如果你保持状态,你总是会遇到无法按F5并且无法为页面添加书签的问题。

    在这种情况下,反向链接是一个简单的 ActionLink。

    网址是:

    /YourController/List/YourParentParameterValue

    /YourController/Detail/YourParentParameterValue/YourDetailParameterValue

    /YourController/Create/YourParentParameterValue

    【讨论】:

      猜你喜欢
      • 2010-11-10
      • 2011-10-15
      • 2013-01-12
      • 1970-01-01
      • 1970-01-01
      • 2010-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多