2010-04-15 1 views
6

안전한 위치에서 파일을 읽어야하는 작업이 있으므로 가장을 사용하여 파일을 읽어야합니다.ASP.NET MVC의 가장

[AcceptVerbs(HttpVerbs.Get)] 
public ActionResult DirectDownload(Guid id) 
{ 
    if (Impersonator.ImpersonateValidUser()) 
    { 
     try 
     { 
      var path = "path to file"; 
      if (!System.IO.File.Exists(path)) 
      { 
       return View("filenotfound"); 
      } 

      var bytes = System.IO.File.ReadAllBytes(path); 
      return File(bytes, "application/octet-stream", "FileName"); 
     } 
     catch (Exception e) 
     { 
      Log.Exception(e); 
     }finally 
     { 
      Impersonator.UndoImpersonation(); 
     } 
    } 
    return View("filenotfound"); 
} 

위의 코드 유일한 문제는 내가 메모리에 전체 파일을 읽어해야한다는 것입니다 내가 아주 큰 파일을 처리 할 것입니다, 그래서 이것은되지 않습니다 :

이 코드는 WORKS 좋은 해결책. 그러나 나는이 2 개 라인 교체 할 경우이와

var bytes = System.IO.File.ReadAllBytes(path); 
return File(bytes, "application/octet-stream", "FileName"); 

:

return File(path, "application/octet-stream", "FileName"); 

작동하지 않습니다와 나는 오류 메시지가 얻을 : 경로 'C에서

액세스 : \ projects \ uploads \ 1 \ aa2bcbe7-ea99-499d-add8-c1fdac561b0e \ Untitled 2.csv '가 거부되었습니다.

경로와 함께 파일 결과를 사용하는 것이 가장 가깝게 "실행 취소"했을 때 나중에 요청 파이프 라인에서 파일을 열려고합니다.

바이트 배열의 파일을 읽을 수 있으므로 가장 (impersonation) 코드가 작동합니다. 내가하고 싶은 것은 파일을 클라이언트로 스트리밍하는 것이다.

어떻게하면 해결할 수 있습니까?

미리 감사드립니다.

답변

4

사용자 정의 FilePathResult 작성하려고 할 수 있습니다 :

public class ImpersonatingFileResult : FilePathResult 
{ 
    public ImpersonatingFileResult(string fileName, string contentType) 
     : base(fileName, contentType) 
    { } 

    protected override void WriteFile(HttpResponseBase response) 
    { 
     // TODO : Start impersonation 
     response.TransmitFile(FileName); 
     // TODO : Rollback impersonation 
    } 
} 

와 컨트롤러 :

return new ImpersonatingFileResult(path, "application/octet-stream"); 
+0

위대한 성과를 보았습니다. 예외가 생기기 때문에 조금 변경했습니다 ... Impersonator.ImpersonateValidUser(); response.WriteFile (FileName); response.Flush(); response.End(); Impersonator.UndoImpersonation(); – Emad

+0

네, 좋은 시작입니다.그러나 특정 버전의 IIS에서는 가장을 기반으로하지 않고 파일 제공에 따라 "잘못된 핸들"오류가 발생합니다. – Greg

1

내가 대린의 대답을 좋아,하지만 그것은 가장 로직을 생략하고, 오류가 발생합니다 IIS 7에서 ... N을 사용하여 가능한 가장 수 코드를 추가했습니다. uget 패키지 SimpleImpersonation.

또한 IIS 7에서 잘못된 핸들 오류를 방지하기 위해 몇 가지 변경 사항이 발생했습니다. 컨트롤러를 사용하여

public class ImpersonatingFileResult : FilePathResult 
{ 
    public ImpersonatingFileResult(string fileName, string contentType) 
     : base(fileName, contentType) 
    { } 

    protected override void WriteFile(HttpResponseBase response) 
    { 
     using (SimpleImpersonation.Impersonation.LogonUser(domain: "SomeDomain", username: "SomeUser", password: "SomePassword", logonType: SimpleImpersonation.LogonType.NewCredentials)) 
     { 
      response.Clear(); 
      response.ContentType = base.ContentType; 
      response.AddHeader("Content-Disposition", "attachment; filename=" + System.IO.Path.GetFileName(base.FileName)); 
      response.TransmitFile(FileName); 
      response.Flush(); 
     } 
    } 

: 그리고

 return new ImpersonatingFileResult(someFilePath, "Application/pdf"); 

을 위의 파일을 다운로드하지만, 당신이 그것을 표시하려는 경우, 당신은 "인라인"를 지정해야합니다.

  response.Clear(); 
      response.ContentType = base.ContentType; 
      response.AddHeader("Content-Disposition", "inline; filename=\"" + System.IO.Path.GetFileName(base.FileName) + "\""); 
      response.TransmitFile(FileName); 
      response.Flush(); 
+0

이것은 훌륭한 대답입니다. 감사합니다. –