在ASP.NET中以中间信任级别存储临时用户文件

5
我有一个场景,我的ASP.NET Web应用程序的用户提交包含文本信息和图像的推荐。提交过程分为以下几步骤:
- 首先,用户输入内容并选择图像路径。 - 当他点击预览时,再次显示信息以便确认。 - 一旦确认,信息将被保存在数据库中。
这样做的问题在于,在用户实际确认之前,我不想将上传的图像存储在数据库中。相反,我将它们作为临时文件存储,并仅在最终确认后将它们放入数据库中。
由于我还希望我的应用程序在中等信任级别下运行,因此我只有对应用程序目录和其他地方没有写权限。我甚至想限制ASPNET / NETWORK SERVICE用户对~/App_Data文件夹的写权限。我的情况是,一旦在此文件夹中创建了临时文件,应用程序池就会被重新启动,而我不希望在每个推荐提交时都这样做。
您建议我如何保存这些临时文件?如果我更新文件,池不会重新启动——只有在创建或重命名时才会重新启动。但我不认为我可以将整个图像存储在单个文件中供所有用户使用。您怎么看?
更新:我应该指出,我正在使用第三方控件进行上传。它允许我在上传后以编程方式访问文件内容的二进制流,但我无法在第二次回发后保留它(第一步和回发实际上执行上传)。

应用程序池在该场景下不应该回收。也许是web.config中的错误条目? - leppie
4个回答

5
我建议使用孤立存储。它是一种虚拟文件夹。
以下是CodeProject上的一个示例节选:
IsolatedStorageFileStream stream = 
  new IsolatedStorageFileStream(ISOLATED_FILE_NAME, 
  FileMode.Create, isoStore);

StreamWriter writer = new StreamWriter( stream );
writer.WriteLine( "This is my first line in the isolated storage file." );
writer.WriteLine( "This is second line." );
writer.Close();

更新:要清理您的文件,请执行以下操作:

string fileName = "isolatestorage.txt";

IsolatedStorageFile storage = IsolatedStorageFile.GetStore(
    IsolatedStorageScope.User | IsolatedStorageScope.Assembly, null, null);

string[] files = storage.GetFileNames(fileName);
foreach(string file in files) {
    if(file == fileName) {
        storage.DeleteFile(file);
        break;
    }
}

是的,我正在考虑这个问题。问题在于,我该如何清空它呢?毕竟它不是一个临时文件夹 - 而是用于长期持久化的。 - Slavo
你可以运行一个定时任务来检查并清空它。 - chakrit
@Seb - 我知道如何在代码中实现 - 我只需要定期自动完成这个任务。@Chakrit - 有点过度了。我不敢相信没有其他人遇到过这样的问题。 - Slavo
IsolatedStorage可能不错,但也不是必需的。它使用Windows用户名进行隔离,在这里并不是很适用,对吧? - Scott Stafford
@ScottStafford 我不确定。我认为它使用运行应用程序的 Windows 帐户,所以不应该有问题。 - Seb Nilsson

2

在ASP.NET场景中,您仍然可以使用普通的Path.GetTempFilename()方法获取临时文件。

它应该会给您一个可由NETWORK_SERVICE编写但也存在于实际Windows临时文件夹之一而不是应用程序文件夹的临时文件路径。

如果您的主机正确配置了服务器,那么这应该可以正常工作。


2
默认的web_mediumtrust.config文件非常不实用。
以下是默认web_mediumtrust.config文件的一部分。 默认情况下,您不能使用System.IO来查找或写入临时文件夹。
                        <IPermission
                                class="FileIOPermission"
                                version="1"
                                Read="$AppDir$"
                                Write="$AppDir$"
                                Append="$AppDir$"
                                PathDiscovery="$AppDir$"
                        />

虽然我没有像@Seb提到的那样使用隔离存储,但似乎默认的配置文件允许它。


0

通常,只有 bin 和 App_Code 目录中的更改才会导致应用程序池重新启动。 - leppie

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