2013-01-03 36 views
8

Sau khi quản lý để tải dữ liệu vào Máy chủ Rails của tôi qua C# (kiểm tra here để biết tôi đang nói về cái gì), tôi đang cố gắng tải tệp lên cùng máy chủ đó, cùng với dữ liệu khác.Tải tệp lên qua C# bằng cách sử dụng yêu cầu JSON và RestSharp

Trong Ruby, tôi có thể làm điều này với các mã:

require 'HTTMultiParty' 

    class ReceiptCreate 
     include HTTMultiParty 
     # Log to file 
     # debug_output File.new("httparty1.log", "w+") 
     base_uri "localhost:3000" 
     format :json 
     headers "Accept" => "application/json" 

     def initialize 
     end 

     def post(machine_serial,filepath,tag_number,token) 
     options = { body: 
        {receipt: 
         {tag_number:tag_number, 
         receipt_file: File.new(filepath), 
         ispaperduplicate:0 
         }, 
        machine: 
         {serial_number: machine_serial, 
         safe_token: token 
         } 
        }    
       } 
     self.class.post('/receipts', options) 
     end 
    end 

receipt = ReceiptCreate.new() 
filename1 = "C:\\filename1.pdf" 
filename2 = "C:\\filename2.pdf" 
response=receipt.post("2803433",filename2,"p94tt7w","123") 
puts response 

một khi tôi kiểm tra các thông số trên máy chủ ray i

Parameters: {"receipt"=>{"tag_number"=>"p94tt7w", "receipt_file"=>#<ActionDispatch::Http::UploadedFile:0x4183ea8 @original_filename="Invoice.pdf", @content_type="application/octet-stream", @headers="Content-Disposition: form-data; name=\"receipt[receipt_file]\"; filename=\"Invoice.pdf\"\r\nContent-Length: 11653\r\nContent-Type: application/octet-stream\r\nContent-Transfer-Encoding: binary\r\n", @tempfile=#<File:C:/Users/diogo/AppData/Local/Temp/RackMultipart20130103-18168-efiqia>>, "ispaperduplicate"=>"0"}, "machine"=>{"serial_number"=>"2803433", "safe_token"=>"123"}} 

thấy Nhưng nếu tôi cố gắng để làm cùng với # mã c của tôi dưới đây

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using RestSharp; 
using System.Web.Script.Serialization; 
using System.IO; 

namespace RonRestClient 
{ 


    class templateRequest 
    { 
     public Receipt receipt; 
     public class Receipt 
     { 
      public float total; 
      public String tag_number; 
      public bool ispaperduplicate = true; 
      public byte[] receipt_file; 
      public Receipt(float total, String tagnr, string filepath) 
      { 
       this.total = total; 
       this.tag_number = tagnr; 
       this.receipt_file = File.ReadAllBytes(filepath); 
      } 
     }; 
     public Machine machine; 
     public class Machine 
     { 
      public String serial_number; 
      public String safe_token; 
      public Machine(String machinenr, String safe_token) 
      { 
       this.serial_number = machinenr; 
       this.safe_token = safe_token; 
      } 
     }; 
    } 


    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 

      string path = @"C:\filename2.pdf"; 
      string tagnr = "p94tt7w"; 
      string machinenr = "2803433"; 
      string safe_token = "123"; 
      float total = 100; 

      templateRequest req = new templateRequest(); 
      req.receipt = new templateRequest.Receipt(total, tagnr, path); 
      req.machine = new templateRequest.Machine(machinenr, safe_token); 
      //string json_body = JsonConvert.SerializeObject(req); 
      //string json_body = new JavaScriptSerializer().Serialize(req); 


      //var json_body = "{\"receipt\" : {\"total\":"+total+", \"tag_number\":\""+tagnr+"\",\"ispaperduplicate\":true},\"machine\":{\"serial_number\": \""+machinenr+"\",\"safe_token\": \""+safe_token+"\"}}"; 

      var client = new RestClient("http://localhost:3000/receipts"); 

      var request = new RestRequest(Method.POST); 


      //set request Body 
      request.AddHeader("Content-type", "application/json"); 
      request.AddHeader("Accept", "application/json"); 
      request.RequestFormat = DataFormat.Json; 

      request.AddBody(req); 
      //request.AddParameter("application/json", json_body, ParameterType.RequestBody); 

      // easily add HTTP Headers 


      // add files to upload (works with compatible verbs) 
      //request.AddFile("receipt/receipt_file",path); 

      // execute the request 

      IRestResponse response = client.Execute(request); 
      var content = response.Content; // raw content as string 
      if(response.ErrorMessage !="") content += response.ErrorMessage; 
      response_box.Text = content; 




     } 
    } 
} 

tôi có được điều này

012.
Parameters: {"receipt"=>{"total"=>100, "tag_number"=>"p94tt7w", "ispaperduplicate"=>true, "receipt_file"=>[37, 80, [n3...nX], 10]}, "machine"=>{"serial_number"=>"2803433", "safe_token"=>"123"}} 

Điều này dường như có nghĩa là Restsharp chỉ nghĩ rằng tệp của tôi chỉ là một trường khác.

RestSharp dường như có một phương pháp để thêm các tập tin request.AddFile("receipt/receipt_file",path);, và tôi tin rằng điều này có lẽ nên được con đường để đi ... nhưng khi tôi chỉ cần cố gắng và thêm các tập tin, tôi nhận được một thông báo lỗi nói:

Không thể đặt thuộc tính này sau khi bắt đầu viết.

Tôi có cần đặt riêng từng thuộc tính của tệp không?

EDIT

Trong khi đó tôi tìm thấy post này, thay đổi mã của tôi để:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using RestSharp; 
using System.Web.Script.Serialization; 
using System.IO; 
using System.Net; 

namespace RonRestClient 
{ 


    class templateRequest 
    { 
     public Receipt receipt; 
     public class Receipt 
     { 
      //public float total; 
      public String tag_number; 
      public bool ispaperduplicate = true; 
      //public byte[] receipt_file; 
      public Receipt(String tagnr) 
      { 
       //this.total = total; 
       this.tag_number = tagnr; 
       // this.receipt_file = File.ReadAllBytes(filepath); 
      } 
     }; 
     public Machine machine; 
     public class Machine 
     { 
      public String serial_number; 
      public String safe_token; 
      public Machine(String machinenr, String safe_token) 
      { 
       this.serial_number = machinenr; 
       this.safe_token = safe_token; 
      } 
     }; 
    } 


    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 

      string path = @"C:\filename2.pdf"; 
      string tagnr = "p94tt7w"; 
      string machinenr = "2803433"; 
      string safe_token = "123"; 
      float total = 100; 

      templateRequest req = new templateRequest(); 
      req.receipt = new templateRequest.Receipt(tagnr); 
      req.machine = new templateRequest.Machine(machinenr, safe_token); 

      var request = new RestRequest("/receipts",Method.POST); 
      request.AddParameter("receipt[total]", total); 
      request.AddParameter("receipt[tag_number]", tagnr); 
      request.AddParameter("machine[serial_number]", machinenr); 
      request.AddParameter("machine[safe_token]", safe_token); 
      request.AddFile("receipt[receipt_file]", File.ReadAllBytes(path), "Invoice.pdf", "application/octet-stream"); 

      // Add HTTP Headers 
      request.AddHeader("Content-type", "application/json"); 
      request.AddHeader("Accept", "application/json"); 
      request.RequestFormat = DataFormat.Json; 
      //set request Body 
      //request.AddBody(req); 


      // execute the request 
      //calling server with restClient 
      RestClient restClient = new RestClient("http://localhost:3000"); 
      restClient.ExecuteAsync(request, (response) => 
      { 

       if (response.StatusCode == HttpStatusCode.OK) 
       { 
        //upload successfull 
        MessageBox.Show("Upload completed succesfully...\n" + response.Content); 
       } 
       else 
       { 
        //error ocured during upload 
        MessageBox.Show(response.StatusCode + "\n" + response.StatusDescription); 
       } 
      }); 

     } 

    } 

} 

và bây giờ nhận được các thông số:

Parameters: {"receipt"=>{"total"=>"100", "tag_number"=>"p94tt7w", "receipt_file"=>#<ActionDispatch::Http::UploadedFile:0x3db42d8 @original_filename="Invoice.pdf", @content_type="application/octet-stream", @headers="Content-Disposition: form-data; name=\"receipt[receipt_file]\"; filename=\"Invoice.pdf\"\r\nContent-Type: application/octet-stream\r\n", @tempfile=#<File:C:/Users/diogo/AppData/Local/Temp/RackMultipart20130103-18168-9mbt3h>>}, "machine"=>{"serial_number"=>"2803433", "safe_token"=>"123"}} 

Cùng với một HTTP 422 - Không thể xử lý Lỗi thực thể.

Nếu tôi so sánh các tham số này với thông số tôi đang làm việc từ mã ruby, giờ đây sự khác biệt duy nhất có vẻ là thông báo cuối cùng này không có trường Độ dài nội dung và Mã hóa nội dung chuyển.

Bạn có ý tưởng nào về cách tôi có thể thêm thuộc tính không?

Trả lời

13

Đây là cuộc chiến ... Cuối cùng, tôi đã khám phá hai cách khác nhau để giải quyết vấn đề này. Sự trớ trêu của nó, như rất nhiều vấn đề mã hóa, là tất cả những gì tôi phải làm là thiết lập các thông số đúng ở vị trí đầu tiên ... Chỉ một thông số còn thiếu khiến tôi mất hơn 4 giờ ..

Cả hai chi tiết dưới đây:

1 - Sử dụng RestSharp (tổng lĩnh vực không nên có mặt ở đó, và lĩnh vực ispaperduplicate đã mất tích)

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using RestSharp; 
using System.Web.Script.Serialization; 
using System.IO; 
using System.Net; 

namespace RonRestClient 
{  

    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 

      string path = @"C:\filename2.pdf"; 
      //localhost settings 
      string requestHost = @"http://localhost:3000/receipts"; 
      string tagnr = "p94tt7w"; 
      string machinenr = "2803433"; 
      string safe_token = "123"; 

      // Do it with RestSharp 

      templateRequest req = new templateRequest(); 
      req.receipt = new templateRequest.Receipt(tagnr); 
      req.machine = new templateRequest.Machine(machinenr, safe_token); 

      var request = new RestRequest("/receipts", Method.POST); 
      request.AddParameter("receipt[tag_number]", tagnr); 
      request.AddParameter("receipt[ispaperduplicate]", 0); 
      request.AddParameter("machine[serial_number]", machinenr); 
      request.AddParameter("machine[safe_token]", safe_token); 
      request.AddFile("receipt[receipt_file]", File.ReadAllBytes(path), Path.GetFileName(path), "application/octet-stream"); 

      // Add HTTP Headers 
      request.AddHeader("Content-type", "application/json"); 
      request.AddHeader("Accept", "application/json"); 
      request.RequestFormat = DataFormat.Json; 
      //set request Body 
      //request.AddBody(req); 


      // execute the request 
      //calling server with restClient 
      RestClient restClient = new RestClient("http://localhost:3000"); 
      restClient.ExecuteAsync(request, (response) => 
      { 

       if (response.StatusCode == HttpStatusCode.OK) 
       { 
        //upload successfull 
        MessageBox.Show("Upload completed succesfully...\n" + response.Content); 
       } 
       else 
       { 
        //error ocured during upload 
        MessageBox.Show(response.StatusCode + "\n" + response.StatusDescription); 
       } 
      }); 

     } 

    } 

} 

2 - Sử dụng FileStream với HttpWebRequest (cảm ơn bạn Clivant)

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using RestSharp; 
using System.Web.Script.Serialization; 
using System.IO; 
using System.Net; 

namespace RonRestClient 
{ 

    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 

      string path = @"C:\Projectos\My Training Samples\Adobe Sample\RBO1574.pdf"; 
      //localhost settings 
      string requestHost = @"http://localhost:3000/receipts"; 
      string tagnr = "p94tt7w"; 
      string machinenr = "2803433"; 
      string safe_token = "123"; 

      FileStream fs1 = File.OpenRead(path); 
      long filesize = fs1.Length; 
      fs1.Close(); 

      // Create a http request to the server endpoint that will pick up the 
      // file and file description. 
      HttpWebRequest requestToServerEndpoint = 
       (HttpWebRequest)WebRequest.Create(requestHost); 

      string boundaryString = "FFF3F395A90B452BB8BEDC878DDBD152"; 
      string fileUrl = path; 

      // Set the http request header \\ 
      requestToServerEndpoint.Method = WebRequestMethods.Http.Post; 
      requestToServerEndpoint.ContentType = "multipart/form-data; boundary=" + boundaryString; 
      requestToServerEndpoint.KeepAlive = true; 
      requestToServerEndpoint.Credentials = System.Net.CredentialCache.DefaultCredentials; 
      requestToServerEndpoint.Accept = "application/json"; 


      // Use a MemoryStream to form the post data request, 
      // so that we can get the content-length attribute. 
      MemoryStream postDataStream = new MemoryStream(); 
      StreamWriter postDataWriter = new StreamWriter(postDataStream); 

      // Include value from the tag_number text area in the post data 
      postDataWriter.Write("\r\n--" + boundaryString + "\r\n"); 
      postDataWriter.Write("Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}", 
            "receipt[tag_number]", 
            tagnr); 

      // Include ispaperduplicate text area in the post data 
      postDataWriter.Write("\r\n--" + boundaryString + "\r\n"); 
      postDataWriter.Write("Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}", 
            "receipt[ispaperduplicate]", 
            0); 

      // Include value from the machine number in the post data 
      postDataWriter.Write("\r\n--" + boundaryString + "\r\n"); 
      postDataWriter.Write("Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}", 
            "machine[serial_number]", 
            machinenr); 

      // Include value from the machine token in the post data 
      postDataWriter.Write("\r\n--" + boundaryString + "\r\n"); 
      postDataWriter.Write("Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}", 
            "machine[safe_token]", 
            safe_token); 

      // Include the file in the post data 
      postDataWriter.Write("\r\n--" + boundaryString + "\r\n"); 
      postDataWriter.Write("Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n" 
            + "Content-Length: \"{2}\"\r\n" 
            + "Content-Type: application/octet-stream\r\n" 
            + "Content-Transfer-Encoding: binary\r\n\r\n", 
            "receipt[receipt_file]", 
            Path.GetFileName(fileUrl), 
            filesize); 

      postDataWriter.Flush(); 


      // Read the file 
      FileStream fileStream = new FileStream(fileUrl, FileMode.Open, FileAccess.Read); 
      byte[] buffer = new byte[1024]; 
      int bytesRead = 0; 
      while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0) 
      { 
       postDataStream.Write(buffer, 0, bytesRead); 
      } 
      fileStream.Close(); 

      postDataWriter.Write("\r\n--" + boundaryString + "--\r\n"); 
      postDataWriter.Flush(); 

      // Set the http request body content length 
      requestToServerEndpoint.ContentLength = postDataStream.Length; 

      // Dump the post data from the memory stream to the request stream 
      Stream s = requestToServerEndpoint.GetRequestStream(); 

      postDataStream.WriteTo(s); 

      postDataStream.Close(); 

     } 

    } 

} 
Các vấn đề liên quan