如何将对象列表存储到ViewState中

13

我有一个类型为List<JobSeeker>的列表。我想将它存储在ViewState中。如何实现?

private List<JobSeeker> JobSeekersList { get; set; }
2个回答

23

基本上您只需要使用get,然后在获取时,要么从视图状态中获取已发布的数据,要么在视图状态上第一次设置它。这是更健壮的代码,可避免每次调用时的所有检查(是否设置了视图状态、是否存在等),直接保存并使用视图状态对象。

// using this const you avoid bugs in mispelling the correct key.
const string cJobSeekerNameConst = "JobSeeker_cnst";

public List<JobSeeker> JobSeekersList
{
    get
    {
        // check if not exist to make new (normally before the post back)
        // and at the same time check that you did not use the same viewstate for other object
        if (!(ViewState[cJobSeekerNameConst] is List<JobSeeker>))
        {
            // need to fix the memory and added to viewstate
            ViewState[cJobSeekerNameConst] = new List<JobSeeker>();
        }

        return (List<JobSeeker>)ViewState[cJobSeekerNameConst];
    }
}

避免使用is的替代方案

// using this const you avoid bugs in mispelling the correct key.
const string cJobSeekerNameConst = "JobSeeker_cnst";

public List<JobSeeker> JobSeekersList
{
    get
    {
        // If not on the viewstate then add it
        if (ViewState[cJobSeekerNameConst] == null)                
            ViewState[cJobSeekerNameConst] = new List<JobSeeker>();

        // this code is not exist on release, but I check to be sure that I did not 
        //  overwrite this viewstate with a different object.
        Debug.Assert(ViewState[cJobSeekerNameConst] is List<JobSeeker>);

        return (List<JobSeeker>)ViewState[cJobSeekerNameConst];
    }
}

并且JobSeeker类必须标记为[Serializable]

[Serializable]
public class JobSeeker
{
    public int ID;
    ...
}

您可以像普通对象一样对其进行调用,它永远不会为空。在提交回发后,也将返回保存在视图状态中的值。

JobSeekersList.add(new JobSeeker(){ID=1});
var myID = JobSeekersList[0].ID;

ињРзЃЧзђ¶ as еТМ !=null жѓФ is еТМ cast жЫійЂШжХИгАВ - abatishchev
@abatishchev 谢谢你的留言,我会去查看一下。你是如何定义“更有效率”的?代码要么能够工作,要么不能。有更多的延迟,更多的汇编运行吗?会失败吗? - Aristos
@abatishchev 我读了那篇文章,但我不明白为什么在我的情况下 is 不高效 - 我使用它来双重检查对象是否已设置,如果已设置,则必须与我想要的对象相同。这与您提供的页面上的示例不同。 - Aristos

3
private IList<JobSeeker> JobSeekersList
{
    get
    {
        // to do not break SRP it's better to move check logic out of the getter
        return ViewState["key"] as List<JobSeeker>;
    }
    set
    {
        ViewState["key"] = value;
    }
}

好的,使用这段代码时,您需要仔细检查列表是否存在,或者是否进行了回传,然后将其设置在视图状态中。我的意思是,在此处,您还需要编写更多的代码来处理JobSeekersList,因为您没有将其保存在视图状态中。 - Aristos
@Aristos:我知道,但否则它将会违反单一职责原则——一个方法将执行保存和检查两个操作,这不是最好的解决方案。因此,最好将检查逻辑移到外部,并将属性仅用作视图状态管理器。 - abatishchev
“原则”如果需要,可以被打破。如果您想将其保存到视图状态中以便查看,则需要不犯任何错误并覆盖它,双重检查是否存在ispost back等。通过将其放置在内部,可以避免出现错误。 - Aristos
@Aristos:顺便说一下,我的初始代码正在执行这样的检查。只是它使用了另一个运算符来完成相同的操作。但现在我已经编辑过它,以明确强调我的观点。 - abatishchev
@Aristos:两个不同的getter可能有不同的“需求”:一个想要创建一个列表,另一个则不需要。为了避免这种情况,您不会在属性中放置任何额外的逻辑,使其保持轻量级并仅满足一个需求。 - abatishchev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接