2012-03-16 2 views
0

에 ZipOutputStream이에서 파일을 업로드하고 나는 내 MVC 포스트 행동을 직접 만들어 압축 된 내용을 업로드하고 싶습니다. 성공적으로 내 MVC 작업을 가져올 때 게시 된 데이터로 내 작업 메서드의 매개 변수를 null로 게시하지만 점점. 여기 는 <strong>SharpZipLib</strong>에서 내가 <strong>ZipOutputStream이</strong>을 사용하고 MVC 3 액션

내가 이것을 테스트하기 위해 사용하고 내 테스트 코드입니다 :

public void UploadController_CanUploadTest() 
    { 
     string xml = "<test>xml test</test>" 
     string url = "http://localhost:49316/Api/DataUpload/Upload/"; 

     WebClient client = new WebClient(); 

     var cc= new CredentialCache(); 
     cc.Add(new Uri(url), 
       "Basic", 
       new NetworkCredential("Testuser", "user")); 

     client.Credentials = cc; 

     string _UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)"; 
     client.Headers.Add(HttpRequestHeader.UserAgent, _UserAgent); 
     client.Headers["Content-type"] = "application/x-www-form-urlencoded"; 

     using (var stream = client.OpenWrite(url, "POST")) 
     { 
      Zipped zip = new Zipped(stream, Encoding.UTF8, false); 

      FileContent content = new FileContent("Upload", xml); 

      var uploads = new List<FileContent>(); 
      uploads.Add(content); 

      zip.Compress(uploads); 

      stream.Flush(); 
      stream.Close(); 
     } 
    } 

이 내 압축 클래스 래퍼입니다 :

[HttpPost] 
    public ActionResult Upload(HttpPostedFileBase uploaded) 
    { 
     // uploaded is null at this point 
    } 
: 여기
public class Zipped : ICompression, IDisposable 
{ 
    private Stream _stream = null; 
    private bool _closeStreamOnDispose = true; 
    private Encoding _encoding; 

    public Zipped() 
     : this(new MemoryStream()) 
    { 

    } 

    public Zipped(Stream stream) 
     : this(stream, Encoding.UTF8, true) 
    { 
    } 

    public Zipped(Stream stream, Encoding encoding) 
     : this(stream, encoding, true) 
    { 
    } 

    public Zipped(Stream stream, Encoding encoding, bool closeStreamOnDispose) 
    { 
     _stream = stream; 
     _closeStreamOnDispose = closeStreamOnDispose; 
     _encoding = encoding; 
    } 

    public Stream Compress(IList<FileContent> dataList) 
    { 
     ZipOutputStream outputStream = new ZipOutputStream(_stream); 
     outputStream.SetLevel(9); 

     foreach (var data in dataList) 
     { 
      ZipEntry entry = new ZipEntry(data.Name); 
      entry.CompressionMethod = CompressionMethod.Deflated; 

      outputStream.PutNextEntry(entry); 

      byte[] dataAsByteArray = _encoding.GetBytes(data.Content); 

      outputStream.Write(dataAsByteArray, 0, dataAsByteArray.Length); 
      outputStream.CloseEntry(); 
     } 

     outputStream.IsStreamOwner = false; 
     outputStream.Flush(); 
     outputStream.Close(); 

     return _stream; 
    } 

    public List<FileContent> DeCompress() 
    { 
     ZipInputStream inputStream = new ZipInputStream(_stream); 
     ZipEntry entry = inputStream.GetNextEntry(); 

     List<FileContent> dataList = new List<FileContent>(); 

     while(entry != null) 
     { 
      string entryFileName = entry.Name; 

      byte[] buffer = new byte[4096];  // 4K is optimum 

      // Unzip file in buffered chunks. This is just as fast as unpacking to a buffer the full size 
      // of the file, but does not waste memory. 
      // The "using" will close the stream even if an exception occurs.     
      using (MemoryStream tempMemoryStream = new MemoryStream()) 
      { 
       StreamUtils.Copy(inputStream, tempMemoryStream, buffer); 

       string copied = _encoding.GetString(tempMemoryStream.ToArray()); 
       dataList.Add(new FileContent(entry.Name, copied)); 
      } 

      entry = inputStream.GetNextEntry(); 
     } 

     return dataList; 

    } 

    public void Dispose() 
    { 
     if(_closeStreamOnDispose) 
      _stream.Dispose(); 
    } 

내 간단한 MVC 동작입니다

답변

1

컨트롤러 작업에서 HttpPostedFileBase을 사용하려면 multipart/form-data을 보내야합니다. 클라이언트로부터의 요청이며 application/x-www-form-urlencoded이 아닙니다.

사실 콘텐츠 형식을 application/x-www-form-urlencoded으로 설정했지만 유효하지 않은 요청에 원시 바이트를 직접 쓰고 있기 때문에이를 준수하지 않습니다. 실제로 HTTP 프로토콜 표준을 따르지는 않지만 HttpPostedFileBase 대신 컨트롤러에서 원시 요청 스트림을 읽는다면 여전히 작동 할 수 있습니다. 나는 당신이 그 길로가는 것을 추천하지 않을 것이다.

그래서 당신은 다음과 같이해야한다 보내는 올바른 HTTP 요청 :이 파일의 내용 어디서나 나타나지 않도록

Content-Type: multipart/form-data; boundary=AaB03x 

--AaB03x 
Content-Disposition: form-data; name="uploaded"; filename="input.zip" 
Content-Type: application/zip 

... byte contents of the zip ... 
--AaB03x-- 

경계

가 선택해야합니다.

나는 어떻게 할 수 있었는지에 대한 예를 블로그에 올렸다. upload multiple files.

+0

고마워요. 나는 이것에 대한 예를 보았지만 그 이유에 대해서는 결코 설명하지 못했다. 나는 이걸 줄거야. – dreza

관련 문제