2014-10-14 5 views
0

상황에 내가 사용자가 다음 표에 표시됩니다 파일을 업로드 할 수 있도록하고 내 ASP.Net MVC 프로젝트에서숨겨진 필드

대 세션에서 저장되지 않은 파일의 목록을 지속하기. 이러한 파일은 사용자가 저장 버튼을 클릭 할 때까지 서버에 저장되지 않습니다. 그러나 나는 사용자가 저장되지 않은 파일을보고 삭제할 수 있기를 원하므로 아약스 호출을 통해이를 유지할 수있는 방법이 필요하다. 세션 해결

내가 그것을 세션을 사용하여 한 가지 방법을 수행 한이를 달성합니다. 사용자가 파일을 서버에 저장하는 대신 업로드 할 때 파일 변수와 함께 바이트 배열을 파일에 저장합니다. 아래와 같이. 사용자가

public FileResult LoadFile(string fileName) 
    { 
     List<CustomFile> unsavedFiles = (List<CustomFile>)Session["UnsavedFiles"]; 
     CustomFile requestedFile = unsavedFiles.Single(f => f.FileName == fileName); 

     return File(requestedFile.FileBytes, requestedFile.ContentType 
        , requestedFile.FileName); 
    } 

숨겨진 필드 솔루션 아래와 같이 내가 세션에서 파일을 읽을 수있는 파일을 볼 수 간다 이제

public class CustomFile 
{ 
    //The real class has other properties. Removed for readability 
    public byte[] FileBytes { get; set; } 
    public string FileName{ get; set; } 
    public string ContentType{ get; set; } 

    } 

public void FileUploadComplete(CustomFile file) 
    { 
     List<CustomFile> unsavedFiles = Session["UnsavedFiles"] as List<CustomFile>; 

     if(unsavedFiles == null) 
      unsavedFiles = new List<CustomFiles>(); 

     unsavedFiles.Add(file); 
    } 

그러나 이것은 내가 확실하지 않다 잘 작동 한 페이지에서 저장하지 않은 파일 목록에 액세스하기 만하면이 시나리오에서 Session을 사용하는 것이 적절합니다. 따라서 숨겨진 필드에 "CustomFile"객체의 내 목록을 저장 한 다음이를 내 Actions로 전달하여 정보를 유지할 수 있습니다.

이 주된 문제점은 바이트 배열을 숨겨진 필드에 저장할 문자열로 변환 할 때 각 파일에 사용할 올바른 인코딩을 찾아야한다는 것입니다. 그리고 페이지가 매우 커져서 파일 데이터를 저장할 수 있습니다.

질문

그래서 내가 다른 페이지에 액세스 할 필요가 없습니다 또는 더 적합한 또 다른 해결책이 경우에도 분별이 시나리오에서 세션을 사용하여입니까?

답변

0

대신 숨겨진 세션 개념을 사용하면 좋을 캐싱을 사용하지 않는 것이 좋습니다.

1

파일을 사용자 세션에 저장하는 것은 실제로 그렇게 좋지 않습니다. 100 명의 사용자가 있다고 가정하면 각 파일마다 각각 5MB 씩 1Mb가 업로드됩니다. 메모리 또는 SQL Server에 저장해야하는 500MB의 데이터로 끝납니다. 파일 시스템에 파일을 저장하는 것을 고려해야하며 메모리에 파일 이름 (경로 또는 GUID) 만 저장합니다. 임시 디렉토리를 사용하여 업로드 된 파일을 저장하고 디스크 공간을 정리 한 후 삭제하는 것이 좋습니다. 저장소 파일 시간이 만료 될 때 slidingexpiration 매개 변수 그래서

MemoryCache.Default.Add(FileName, FileName, new CacheItemPolicy 
       { 
        SlidingExpiration = new TimeSpan(0, 60, 0), // 60 minutes 
        RemovedCallback = RemoveFileFromCacheCallback 
       }); 


private void RemoveFileFromCacheCallback(CacheEntryRemovedArguments args) 
{ 
    var fileName = args.CacheItem.Key; 
    var fullFileName = Path.Combine(Path.GetTempPath(), fileName); 

    if (File.Exists(fullFileName)) 
    { 
     File.Delete(fullFileName); 
    } 
} 

때마다 함께 캐시에 파일에 대한 링크를 저장할 수있는 파일을 청소하려면하거나이 임시 디렉토리에서 삭제됩니다 캐시에서 파일 링크를 제거 .