0

我有一个带有ObjectDataSource的GridView。我想让用户创建几个对象,然后一次性保存它们。

背景:我想为食谱创建一个编辑器。食谱具有基本属性(例如名称和来源),并且具有成分(例如 100 克黄油) 我希望用户设置食谱的所有属性并让他在 (!!) 将其保存到数据库之前定义其成分。还必须可以从列表中删除成分。首先保存配方,然后定义成分不是一种选择。

我的问题: 在将成分保存到数据库之前,我应该将它们保存在哪里?

这是我发现的:

  1. ViewState 不是一个选项,因为 ObectDataSource 的 GetData 方法是静态的,因此无法访问视图状态。
  2. 会话不是一个选项,因为用户应该能够同时在同一浏览器的不同选项卡中使用同一页面。
  3. 上下文不是一个选项,因为它不能在回调中存活。
  4. 使用 LinqDataSource 代替 ObectDataSource 不起作用,因为如果数据源不是 linq 数据上下文,它不支持删除操作。
  5. 在 QueryString 中使用唯一 ID(以识别正确的会话对象)将是一种解决方法,但它会弄乱 URL。

我已经在网上搜索了一段时间,并且尝试了很多东西但没有成功。

非常感谢您的任何帮助和任何建议!!

4

2 回答 2

0

最好的办法可能是在页面第一次加载时创建一个临时 ID。将其存储在隐藏字段中,以便 viewstate 知道它。

使用某种自定义类来表示网格的数据。不使用数据源控件,而是使用网格的 DataSource 和 DataMember 属性手动绑定对象。

使用您生成的临时 ID 作为键将此对象存储在缓存中。

在每次回发时,更新缓存中的对象并将其重新绑定到网格。

Viewstate 是通过临时 ID 在客户端上维护身份的机制。asp.net Cache API 维护服务器上的数据状态。

于 2010-01-08T11:49:48.660 回答
0

由于似乎没有更优雅的方法来解决这个问题,我将以下代码实现到我的所有 Web 表单继承的基页面类中:

/// <summary>
/// Set an ID to identify the correct session variable (in case there are several ones).
/// Create this ID when it is needed for the first time.
/// </summary>
private string PageCallID
{
    get
    {
        if (ViewState["PageCallID"] == null) ViewState["PageCallID"] = Guid.NewGuid().ToString("N");
        return ViewState["PageCallID"].ToString();
    }
}

/// <summary>
/// Use a hashtable which is stored into the Session to save the in-memory
/// objects. This helps to keep the viewstate variable at the client small.
/// </summary>
protected Hashtable ServerViewState
{
    get
    {
        string strSessionKey = String.Format("CleverViewState_{0}", PageCallID);
        if (Session[strSessionKey] == null) Session[strSessionKey] = new Hashtable();
        return (Hashtable)Session[strSessionKey];
    }
}

有了这个,我们可以在任何网络表单上写:

ServerViewState["MyDataTable"] = myDataTable;

代替

ViewState["MyDataTable"] = myDataTable;

但是,不能通过静态方法调用此解决方案。所以我认为这更像是一种解决方法而不是解决方案。

如果有人知道解决此问题的更好方法,我将不胜感激任何反馈!

于 2010-01-08T20:30:08.603 回答