如何在会话中使此对象存在?

时间:2015-05-29 21:58:24

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

这是交易:我有一个网站,多个人将共享同一个帐户,每个人都可以在一个上传文件的页面上,并保留他们上传该会话的文件列表。文件上传页面的控制器看起来像

public class FileUploadController : Controller
{

   // ...

    private List<ThreePartKey> uploadedFiles = new List<ThreePartKey> ();

    public ActionResult Index ( )

    {
          // ...
    }

    [HttpPost]
    public ActionResult Index (HttpPostedFileBase file)
    {
         // ...

        if (!errorOccured)
        {
            uploadedFiles.Add(new ThreePartKey { orgname = selectedOrgName, catname = selectedCatName, filename = fileNameNoExtension, fullfilepath = newFileUrlPathAndName });
        }

        // ...
   }

问题是uploadedFiles每次调用[HttpPost] public ActionResult Index (HttpPostedFileBase file)时都会重新初始化,这意味着用户的上传文件列表只显示上次上传的文件。所以我试着尝试

private static List<ThreePartKey> uploadedFiles = new List<ThreePartKey> ();

并且搞砸了所有内容,因为所有已登录的用户都共享相同的列表。

有什么简单的方法可以做我想做的事情吗?

2 个答案:

答案 0 :(得分:2)

每次请求都会实例化并销毁

Controller个。如果要在Web服务器中保留信息,强烈建议使用永久性后备存储,例如数据库。

您可以在ASP.NET应用程序(WebForms,MVC,OWIN等)中使用static状态,但这仅建议用于缓存性能。它不能被依赖,因为static状态仅对当前应用程序池(AppDomain实例)中的当前w3wp.exe是本地的 - 如果您的网站在多个池或应用程序域中运行,或者如果您的应用程序重新启动(或由于不活动而被杀死),然后存储的状态将丢失。

答案 1 :(得分:0)

On选项是为每个请求提供“会话”代码/ id。当用户首次连接到您的站点时,会给他们一个会话代码(我使用'代码'来表示它与我们通常称之为'session'的内容无关)。

每个链接都将该会话代码作为网址的一部分,每个帖子都包含会话代码。然后您的上传缓存可以是:

private static ILookup<int, ThreePartKey> uploadedFiles;

(或者你喜欢的字典)

private static IDictionary<int, IList<ThreePartKey>> uploadedFiles;

取决于您的网站其他部分的大小,如果这是可行的 - 在大多数情况下可能不是描述...但可以管理,例如使用IP地址作为'代码'或如果你是使用AnglurJS或单页面应用程序。

正如所指出的,如果重置应用程序池,任何静态/单例缓存仍将丢失,例如通过IIS中的非活动超时设置。

另一种选择是根据用户的IP地址将文件保存在子文件夹中。

你只是规定他们都使用相同的登录,而不是文件的存储方式等,所以这可能对你有用。