2013-01-03 18 views
8

Po zarządzeniu załadowaniem danych do mojego serwera Railsowego przez C# (sprawdź here, aby dowiedzieć się, o czym mówię), próbuję teraz przesłać plik do tego samego serwera, wraz z inne dane.Prześlij plik przez C# za pomocą żądania JSON i RestSharp

W Ruby, jestem w stanie to zrobić z kodem:

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 

się kiedy sprawdzać parametry na serwerze szyn widzę

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"}} 

Ale jeśli próbuję wykonać to samo z moim C# kodu poniżej

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; 




     } 
    } 
} 

uzyskać to

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

Wydaje się to zasadniczo oznaczać, że Restsharp tylko myśli, że mój plik jest po prostu innym polem.

RestSharp wydaje się mieć metodę dodawania plików request.AddFile("receipt/receipt_file",path);, i wierzę, że powinno to prawdopodobnie droga ... ale kiedy po prostu spróbować i dodać plik, pojawia się komunikat o błędzie mówiąc:

Ta właściwość nie może być ustawiona po rozpoczęciu pisania.

Czy muszę osobno ustawić każdy atrybut pliku?

EDIT

Tymczasem znalazłem ten post zmienił mojego kodu:

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); 
       } 
      }); 

     } 

    } 

} 

i teraz otrzymuję parametry:

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"}} 

wraz z HTTP 422 - niedające się przetwarzać Błąd jednostki.

Jeśli mam porównać te parametry z tymi, które mam z kodu ruby, teraz jedyna różnica polega na tym, że ta ostatnia wiadomość nie ma pól Długość treści i Kodowanie transferu zawartości.

Czy masz pojęcie, w jaki sposób mogę dodać atrybuty?

Odpowiedz

13

To była walka ... W końcu odkryłem dwa różne sposoby rozwiązania tego problemu. Ironią tego, jak wiele problemów z kodowaniem, było to, że wszystko, co musiałem zrobić, to ustawić odpowiednie parametry na pierwszym miejscu ... Tylko jeden brakujący parametr kosztował mnie więcej niż 4 godziny.

Oba opisane poniżej:

1 - Zastosowanie RestSharp (pole sumie nie powinno tam być, a pole ispaperduplicate brakowało)

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 - Używaj FileStream z HttpWebRequest (dziękuję 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(); 

     } 

    } 

} 
Powiązane problemy