After controlling the loading of data to my Rails server using C # (check here to find out what I'm talking about), now I am trying to upload a file to this same server along with other data.
In Ruby, I can do this with code:
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
a, when I check the parameters on the rails server, I see
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"}}
But if I try to do the same with my C # code below
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);
I get it
Parameters: {"receipt"=>{"total"=>100, "tag_number"=>"p94tt7w", "ispaperduplicate"=>true, "receipt_file"=>[37, 80, [n3...nX], 10]}, "machine"=>{"serial_number"=>"2803433", "safe_token"=>"123"}}
This seems to mean that Restsharp just thinks my file is just another field.
RestSharp has a method for adding request.AddFile("receipt/receipt_file",path); files request.AddFile("receipt/receipt_file",path); , and I believe that this should probably be the way ... but when I just try to add a file, I get an error:
This property cannot be set after recording starts.
Do I need to set each file attribute separately?
EDIT
Meanwhile, I found this post , changed my code to:
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); } }); } } }
and now I get the parameters:
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"}}
Along with the HTTP 422 error, an unhandled entity.
If I compare these parameters with those that I work from ruby-code, now the only difference is that this last message has no Content-length and Content-Transfer-Encoding ...
Do you have any ideas on how to add attributes?