通过c#使用JSON请求和RestSharp上传文件
本文关键字:RestSharp 文件 求和 请求 使用 JSON 通过 | 更新日期: 2023-09-27 17:50:29
通过c#管理加载数据到我的Rails服务器后(检查这里知道我在说什么),我现在试图将文件上传到同一服务器,以及其他数据。
在Ruby中,我可以这样做:
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
当我检查rails服务器上的参数时,我看到
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"}}
但是如果我尝试在
下面的c#代码中做同样的事情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;
}
}
}
我得到这个
Parameters: {"receipt"=>{"total"=>100, "tag_number"=>"p94tt7w", "ispaperduplicate"=>true, "receipt_file"=>[37, 80, [n3...nX], 10]}, "machine"=>{"serial_number"=>"2803433", "safe_token"=>"123"}}
这似乎意味着Restsharp只是认为我的文件只是另一个字段。
RestSharp似乎有一个方法来添加文件request.AddFile("receipt/receipt_file",path);
,我相信这应该是要走的路…但是当我尝试添加文件时,我得到一个错误消息说:
写入开始后不能设置此属性。
我需要单独设置文件的每个属性吗?
编辑
同时我发现了这篇文章,把我的代码改为:
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);
}
});
}
}
}
,现在我得到参数:
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"}}
伴随着HTTP 422 - Unprocessable Entity错误。
如果我将这些参数与我从ruby代码中工作的参数进行比较,现在唯一的区别似乎是最后一条消息没有Content-length和Content-Transfer-Encoding字段…
你知道我该如何添加属性吗?
这是一场战斗…最后,我发现了两种不同的方法来解决这个问题。具有讽刺意味的是,就像许多编码问题一样,我所要做的就是首先设置正确的参数……仅仅是少了一个参数,我就花了4个多小时。
详情如下:
1 -使用RestSharp (total字段不应该在那里,ispaperduplicate字段丢失)
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 -使用FileStream与HttpWebRequest(谢谢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();
}
}
}