2013-06-03 5 views
6

로컬 명령 행 클라이언트에서 Web-api를 통해 Azure 저장소로 파일을 업로드하려고합니다. 저는 Azure 웹 사이트를 사용하고 있습니다. 클라이언트와 작업하는 것은 문제가되지 않습니다. 그리고 나는 모든 것이 잘 작동하고 있습니다. 내가 로컬로 실행,하지만 최대한 빨리 푸른에 웹 사이트를 배포, 나는 업로드 할 수없는 경우 하늘빛 웹 사이트가 없기 때문에로컬 파일 시스템에 액세스하지 않고 WebApi를 통해 Azure Blob 저장소에 파일 업로드

public async Task<HttpResponseMessage> PostUpload() 
    { 
     // need a local resource to store uploaded files temporarily 
     LocalResource localResource = null; 
     try 
     { 
      // Azure web-site fails here 
      localResource = RoleEnvironment.GetLocalResource("TempStorage"); 
     } 
     catch (Exception e) 
     { 
      return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "Unable to get access to local resources"); 
     } 

     var provider = new MultipartFormDataStreamProvider(localResource.RootPath); 

     // Read the form data. 
     await Request.Content.ReadAsMultipartAsync(provider); 

     // snipped validation code 
     var container = // code to get container 

     foreach (var fileData in provider.FileData) 
     { 
      var filename = GetBlobName(fileData); 
      var blob = container.GetBlockBlobReference(filename); 
      using (var filestream = File.OpenRead(fileData.LocalFileName)) 
      { 
       blob.UploadFromStream(filestream); 
      } 
      File.Delete(fileData.LocalFileName); 
     } 

     return Request.CreateResponse(HttpStatusCode.OK); 
    } 

모든 것이 잘 작동 다음은 웹 API를 코드는 LocalResource에 대한 액세스. Azure Web-Role로 전환해야합니다. 전환 할 수 있지만 로컬 파일 시스템에 액세스하는 것은 모두 나를 괴롭 히고 있습니다.

LocalResource는 MultipartFormDataStreamProvider() 인스턴스에 필요합니다. 그리고 WebApi에 파일을 업로드하는 다른 방법을 찾지 못했습니다. 내 계획은 로컬 HDD에 아무것도 저장하지 않고 channel through upload directly to Azure입니다.

파일을 업로드하는 다른 방법이 있습니까?

p.s. 나는 usages of Shared Access Signatures을 보았습니다. 클라이언트 응용 프로그램에 서명이있는 URL을 제공하고 클라이언트가 Azure 블로그에 직접 업로드 할 수있게되었습니다. 그러나 저는 클라이언트에게 시그니처를 전달하는 것이 얼마나 안전 할 것인지, 아직 안심할 수 있는지 확실하지 않습니다. 나는 클라이언트가 매우 적대적인 환경에서 돌아가고 클라이언트로부터 돌아 오는 것을 신뢰할 수 없다고 생각합니다.

UPD 최종 해결책은 서버에서만 발행되고 클라이언트에게 전달 된 쓰기 전용 공유 액세스 서명을 사용하는 것입니다. 그리고 클라이언트는 파일을 Azure에 직접 업로드합니다. 이렇게하면 업로드 된 파일을 관리하는 번거 로움을 덜 수 있습니다. 그리고 여기 내 솔루션의 more detailed description입니다.

+0

다음 코드로 예외가 발생합니다. "localResource = RoleEnvironment.GetLocalResource ("TempStorage ")" –

+0

REST API를 사용하는 것이 편합니까? –

+0

@BrianDishaw 예외는 "LocalResource, System.Runtime.InteropServices를 얻을 수 없습니다.SEHException (0x80004005) : 외부 구성 요소가 예외를 발생 시켰습니다. "또한이 페이지 (http://msdn.microsoft.com/en-us/library/windowsazure/ee758708.aspx)는 로컬 리소스가 웹 및 웹 사이트가 아닌 작업자 역할 – trailmax

답변

11

이 답변은 찾고자하는 답변이 아니지만, MultiPartFileStreamProvider 및 Path.GetTempPath()를 사용하여 Azure 웹 사이트에서 로컬 저장소를 사용할 수 있습니다. 코드는 LocalResource가 Owin를 통해 작업자 프로세스 자체 호스트 웹 API의 내부를 개최하는 것과 코드를 같이 작동하도록하기 위해이

public async Task<HttpResponseMessage> PostUpload() 
{ 
    var provider = new MultipartFileStreamProvider(Path.GetTempPath()); 

    // Read the form data. 
    await Request.Content.ReadAsMultipartAsync(provider); 

    // do the rest the same  
} 
+0

이제 Azure가 웹 사이트의 TempPath()를 어떻게 관리하고 있으며 얼마나 신뢰할 수 있는지 궁금합니다. 큰 파일 업로드를 통해 반쯤 닦아 낼 수 없습니까? – trailmax

+0

죽은 링크, Daniel. – Bon

+0

임시 디렉토리가 일시적이지 않음을 나타내는 죽은 링크를 제거했습니다. 내 지식에 이것은 여전히 ​​사실입니다. –

1

한 가지 가능한 솔루션과 같을 것입니다. 당신은 단지 RoleEntryPoint의 ONSTART() 메소드 내에서 Owin 호스팅 API를 시동 할 필요가 http://www.asp.net/web-api/overview/hosting-aspnet-web-api/host-aspnet-web-api-in-an-azure-worker-role

:

당신은 간단한 연습을 찾을 수 있습니다. 웹 API 응답에서 Html을 반환 할 수도 있으므로 작업자 역할을 매우 유연한 기본 프로젝트로 만들 수 있습니다.

다음은 위의 링크에서 Owin 호스트 설정하는 방법을 보여주는 간단한 코드 조각입니다 : 내가 파일을 로컬로 먼저 저장되지 않도록 MultipartFormDataStreamProvider을 무시이 StackOverflow의 문서를 발견

+0

방금 ​​웹 롤에 사이트를 배포하고 LocalResource를 사용할 수있었습니다. worker 역할에 web-api를 배치하는 것은 과도한 행동입니다. 어쨌든, 나는 blob 저장소에 쓰기 전용 공유 액세스 서명을 발행하여이 문제를 WebApi를 통해 클라이언트에 전달함으로써이 문제를 해결했습니다. 그런 다음 클라이언트가 파일을 Azure에 직접 업로드합니다. – trailmax

관련 문제