2013-11-05 72 views
0

我有以下.net web api控制器方法,它支持將文件發佈到服務器。我可以將文件和數據發佈到.net mvc web api控制器

public Task<HttpResponseMessage> PostFile() 
      { 
       var request = Request; 
       if (!request.Content.IsMimeMultipartContent()) 
       { 
        throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.UnsupportedMediaType)); 
       } 

       var root = HttpContext.Current.Server.MapPath("~/App_Data/Uploads"); 
       var provider = new MultipartFileStreamProvider(root); 

       var task = request.Content.ReadAsMultipartAsy 

nc(provider).ContinueWith(o => 
      { 
       var finfo = new FileInfo(provider.FileData.First().LocalFileName); 

       var guid = Guid.NewGuid().ToString(); 

       File.Move(finfo.FullName, 
        Path.Combine(root, 
         guid + "_" + provider.FileData.First().Headers.ContentDisposition.FileName.Replace("\"", ""))); 

       return new HttpResponseMessage 
       { 
        Content = new StringContent("File upload.") 
       }; 
      }); 

      return task; 
     } 

這很好,但我希望能夠包含一些關於該文件的元數據作爲帖子的一部分。在我此刻有元數據一樣

public HttpResponseMessage PostTAG(TAG tag) 

這需要在標籤對象的信息,並將其保存到數據庫中不同的Web API方法。如果他們可以在一個請求中將文件和元數據一起發佈,那麼對於我的api客戶端來說會更容易。這是可能的.net網絡API。

+0

也許你可以延長HttpPostedFileBase並添加您元數據。然後在客戶端代碼的方法調用中發送它,以便獲得文件和自定義數據。 –

回答

0

可能的話,您的WEB API爲TAG數據聲明瞭一個參數。問題將是您的客戶將數據發佈到您的WEB API。如果使用.NET客戶端發佈數據到你的WEB API,.NET Web客戶端不支持數據

一起發佈的文件因此,你需要使用較低級別的HttpWebRequest像這樣的一個

public string UploadFilesToRemoteUrl(string url, Dictionary<string, string> files, NameValueCollection nvc, string contenttype) 
     { 
      string boundary = "----------------------------" + 
      DateTime.Now.Ticks.ToString("x"); 

      HttpWebRequest httpWebRequest2 = (HttpWebRequest)GetWebRequest(new Uri(url)); //(HttpWebRequest)WebRequest.Create(url); 
      SetProxy(httpWebRequest2); 
      SetUserAgent(httpWebRequest2); 
      httpWebRequest2.ContentType = "multipart/form-data; boundary=" + boundary; 
      httpWebRequest2.Timeout = WebRequestTimeout; // 60 second * miliseconds * 60 minutes = 1 hour 
      httpWebRequest2.Method = "POST"; 
      httpWebRequest2.KeepAlive = true; 
      httpWebRequest2.Credentials = 
      System.Net.CredentialCache.DefaultCredentials; 

      Stream memStream = new System.IO.MemoryStream(); 
      byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n"); 

      string formdataTemplate = "\r\n--" + boundary + "\r\nContent-Disposition: form-data; name=\"{0}\";\r\n\r\n{1}"; 

      if (nvc != null) 
      { 
       foreach (string key in nvc.Keys) 
       { 
        string formitem = string.Format(formdataTemplate, key, nvc[key]); 
        byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem); 
        memStream.Write(formitembytes, 0, formitembytes.Length); 
       } 
      } 

      memStream.Write(boundarybytes, 0, boundarybytes.Length); 

      string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n\r\n"; 
      if (string.IsNullOrEmpty(contenttype) == false) 
      { 
       headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n" + contenttype + "\r\n"; 
      } 

      string[] keys = nvc.AllKeys; 
      foreach (KeyValuePair<string, string> key in files) 
      { 
       //string header = string.Format(headerTemplate, "file" + i, files[i]); 
       //string header = string.Format(headerTemplate, "uplTheFile", files[i]); 
       string header = string.Format(headerTemplate, key.Key, key.Value); 
       byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header); 

       memStream.Write(headerbytes, 0, headerbytes.Length); 

       FileStream fileStream = new FileStream(key.Value, FileMode.Open, FileAccess.Read); 
       byte[] buffer = new byte[buffsize]; 

       int bytesRead = 0; 

       while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0) 
       { 
        memStream.Write(buffer, 0, bytesRead); 
        int progress = Convert.ToInt32((memStream.Length * 100)/fileStream.Length); 
        ReportProgress(key.Value, progress); 
       } 

       memStream.Write(boundarybytes, 0, boundarybytes.Length); 
       fileStream.Close(); 
       if (MonitoredDownload != null) MonitoredDownload.OnComplete(key.Value); 
       buffer = null; 
       headerbytes = null; 
      } 

      httpWebRequest2.ContentLength = memStream.Length; 

      Stream requestStream = httpWebRequest2.GetRequestStream(); 
      memStream.Position = 0; 
      byte[] tempBuffer = new byte[buffsize]; 
      int bytereads = 0; 
      while ((bytereads = memStream.Read(tempBuffer, 0, tempBuffer.Length)) != 0) 
      { 
       requestStream.Write(tempBuffer, 0, bytereads); 
      } 

      //memStream.Read(tempBuffer, 0, tempBuffer.Length); 
      memStream.Close(); 
      memStream.Dispose(); 
      //requestStream.Write(tempBuffer, 0, tempBuffer.Length); 
      requestStream.Close(); 
      requestStream.Dispose(); 

      WebResponse webResponse2 = httpWebRequest2.GetResponse(); 
      //SaveCookie(webResponse2, new Uri(url).GetLeftPart(UriPartial.Authority)); 
      Stream stream2 = webResponse2.GetResponseStream(); 
      StreamReader reader2 = new StreamReader(stream2); 
      string str = reader2.ReadToEnd(); 
      reader2.Close(); 
      reader2.Dispose(); 

      stream2.Close(); 
      stream2.Dispose(); 
      webResponse2.Close(); 

      httpWebRequest2 = null; 
      webResponse2 = null; 
      tempBuffer = null; 
      return str; 
     } 

TO使用它,只需調用

Dictionary<string,string> dict = new Dictionary<string,string>(); 
dict.Add("file1","c:\\myfile1.jpg"); 
NamuValueCollection nvc = new NameValueCollection(); 
nvc.Add("GPSPosition","somegpsvalue"); 
nvc.Add("CameraModel","somecameramodel"); 
UploadFilesToRemoteUrl("http://www.remoteurl.com/upload", dict, metadata, "Content-Type: application/octet-stream\r\n"); 

上面的代碼摘錄從WebScrapper項目得到了在http://www.sorainnosia.com/Projects#WS

相關問題