如何在 Xamarin 中发送 HTTP POST 请求?
How to send HTTP POST request in Xamarin?
我这里有一个远程地址:
http://damp-sands-2243.herokuapp.com/students
我需要通过 API 电话插入新学生。
这是我用 javasript 做的:
var data = {"name":"Meg",
"regi_number":38};
$(document).ready(function(){
$.ajax({
type: "POST",
url: "/students/",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: JSON.stringify(data),
success: function(){console.log("boo");}
});
});
您可以转到 URL 并使用浏览器的 javascript 控制台来检查它是否有效。
现在,我的问题是从 Xamarin 做同样的事情。
这是我所做的,
try{
string data = "{\"name\":\"Meg\",\"regi_number\":38}";
WebClient client = new WebClient();
client.Encoding = System.Text.Encoding.UTF8;
string reply = client.UploadString("https://damp-sands-2243.herokuapp.com/students/", data);
// Disply the server's response.
Console.WriteLine(reply);
}
catch(Exception ex){
Console.Out.WriteLine("Debug has been started");
Console.Out.WriteLine(ex.GetType().FullName);
Console.Out.WriteLine(ex.GetBaseException().ToString());
}
现在我收到以下错误:
05-10 15:48:11.644 I/mono-stdout(32078): Debug has been started
System.Net.WebException
05-10 15:48:11.645 I/mono-stdout(32078): System.Net.WebException
System.Net.WebException: The remote server returned an error: (422) Unprocessable Entity .
05-10 15:48:11.658 I/mono-stdout(32078): System.Net.WebException: The remote server returned an error: (422) Unprocessable Entity .
at System.Net.HttpWebRequest.CheckFinalStatus (System.Net.WebAsyncResult result) [0x0033b] in :0
at System.Net.HttpWebRequest.SetResponseData (System.Net.WebConnectionData data) [0x00165] in :0
所以错误很简单。如果您访问该页面并在控制台中执行 javascript 代码,您将收到以下请求
POST http://damp-sands-2243.herokuapp.com/students/ HTTP/1.1
Host: damp-sands-2243.herokuapp.com
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:37.0) Gecko/20100101 Firefox/37.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: de,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
X-CSRF-Token: jCQqRuqRk4gEK4+rgybQu2+isCvWXI3oZiWsPyrmHF8mportbRS/pBm761rDrQpDv3TI3JICnE40xK59HQCBOA==
Content-Type: application/json; charset=utf-8
X-Requested-With: XMLHttpRequest
Referer: http://damp-sands-2243.herokuapp.com/students
Content-Length: 31
Cookie: _restest_session=Yi82UXBXeTdmMjFiT0Rud2tNQTlvRUhxZ0VWRndHeUc4TWZLY3M2ejFtcXorTEw1cWIwb1lNRXdUZDlHWnp2bHpuTlVxL1BYdGg2ckNVM0JDWHZZSUJTS3BWU3BRY0diY3NBSUNBQ0l0MEVLYzZCQjB5Z2syK3pmVUFrazQ3UlhsU1B5OGc0cXk4SzkrY0c5VHdoTkc3RnoxSTIvUWswN3ZrQk5QK1pNNVExcG9Bak1qczV4azRtbVpKaTEzRDgyQkoycGlsdy9qanZLem9RazhEelpqT0dnTXdZZldNS3NXcHhnbC8vd1haaW04NXNGUlpSMVlvT0dGeFQvYWlBSzR5SlFyd3RZN2NIQnNBNDYzYUU0ckE9PS0ta1BPN1ZwczJ1bGE2VnhJT0ZWcUhxUT09--2e9406ef247f597812cd2278422527eb2b679e87; request_method=POST
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
{"name":"Meg","regi_number":38}
如您所见,该请求包含一个 cookie 和一个 CSRF-Token。如果您不将它们添加到请求中,它将给出您所面临的 422 错误。
因此,首先您必须向页面发出请求,获取 cookie 和 csrfToken:
WebClient wc = new WebClient();
string baseSiteString = wc.DownloadString("http://damp-sands-2243.herokuapp.com/students");
string csrfToken = Regex.Match(baseSiteString, "<meta name=\"csrf-token\" content=\"(.*?)\" />").Groups[1].Value;
string cookie = wc.ResponseHeaders[HttpResponseHeader.SetCookie];
Console.WriteLine("Token: {0}", csrfToken);
Console.WriteLine("Cookie: {0}", cookie);
下一部分是提出所有重要的请求headers:
wc.Headers.Add(HttpRequestHeader.Cookie, cookie);
wc.Headers.Add(HttpRequestHeader.ContentType, "application/json; charset=utf-8");
wc.Headers.Add(HttpRequestHeader.Accept, "application/json, text/javascript, */*; q=0.01");
wc.Headers.Add("X-CSRF-Token", csrfToken);
wc.Headers.Add("X-Requested-With", "XMLHttpRequest");
string dataString = @"{""name"":""Meg"",""regi_number"":38}";
byte[] dataBytes = Encoding.UTF8.GetBytes(dataString);
byte[] responseBytes = wc.UploadData(new Uri("https://damp-sands-2243.herokuapp.com/students/"), "POST", dataBytes);
string responseString = Encoding.UTF8.GetString(responseBytes);
Console.WriteLine(responseString);
就是这样:)
我这里有一个远程地址: http://damp-sands-2243.herokuapp.com/students
我需要通过 API 电话插入新学生。
这是我用 javasript 做的:
var data = {"name":"Meg",
"regi_number":38};
$(document).ready(function(){
$.ajax({
type: "POST",
url: "/students/",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: JSON.stringify(data),
success: function(){console.log("boo");}
});
});
您可以转到 URL 并使用浏览器的 javascript 控制台来检查它是否有效。
现在,我的问题是从 Xamarin 做同样的事情。 这是我所做的,
try{
string data = "{\"name\":\"Meg\",\"regi_number\":38}";
WebClient client = new WebClient();
client.Encoding = System.Text.Encoding.UTF8;
string reply = client.UploadString("https://damp-sands-2243.herokuapp.com/students/", data);
// Disply the server's response.
Console.WriteLine(reply);
}
catch(Exception ex){
Console.Out.WriteLine("Debug has been started");
Console.Out.WriteLine(ex.GetType().FullName);
Console.Out.WriteLine(ex.GetBaseException().ToString());
}
现在我收到以下错误:
05-10 15:48:11.644 I/mono-stdout(32078): Debug has been started System.Net.WebException 05-10 15:48:11.645 I/mono-stdout(32078): System.Net.WebException System.Net.WebException: The remote server returned an error: (422) Unprocessable Entity . 05-10 15:48:11.658 I/mono-stdout(32078): System.Net.WebException: The remote server returned an error: (422) Unprocessable Entity . at System.Net.HttpWebRequest.CheckFinalStatus (System.Net.WebAsyncResult result) [0x0033b] in :0 at System.Net.HttpWebRequest.SetResponseData (System.Net.WebConnectionData data) [0x00165] in :0
所以错误很简单。如果您访问该页面并在控制台中执行 javascript 代码,您将收到以下请求
POST http://damp-sands-2243.herokuapp.com/students/ HTTP/1.1
Host: damp-sands-2243.herokuapp.com
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:37.0) Gecko/20100101 Firefox/37.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: de,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
X-CSRF-Token: jCQqRuqRk4gEK4+rgybQu2+isCvWXI3oZiWsPyrmHF8mportbRS/pBm761rDrQpDv3TI3JICnE40xK59HQCBOA==
Content-Type: application/json; charset=utf-8
X-Requested-With: XMLHttpRequest
Referer: http://damp-sands-2243.herokuapp.com/students
Content-Length: 31
Cookie: _restest_session=Yi82UXBXeTdmMjFiT0Rud2tNQTlvRUhxZ0VWRndHeUc4TWZLY3M2ejFtcXorTEw1cWIwb1lNRXdUZDlHWnp2bHpuTlVxL1BYdGg2ckNVM0JDWHZZSUJTS3BWU3BRY0diY3NBSUNBQ0l0MEVLYzZCQjB5Z2syK3pmVUFrazQ3UlhsU1B5OGc0cXk4SzkrY0c5VHdoTkc3RnoxSTIvUWswN3ZrQk5QK1pNNVExcG9Bak1qczV4azRtbVpKaTEzRDgyQkoycGlsdy9qanZLem9RazhEelpqT0dnTXdZZldNS3NXcHhnbC8vd1haaW04NXNGUlpSMVlvT0dGeFQvYWlBSzR5SlFyd3RZN2NIQnNBNDYzYUU0ckE9PS0ta1BPN1ZwczJ1bGE2VnhJT0ZWcUhxUT09--2e9406ef247f597812cd2278422527eb2b679e87; request_method=POST
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
{"name":"Meg","regi_number":38}
如您所见,该请求包含一个 cookie 和一个 CSRF-Token。如果您不将它们添加到请求中,它将给出您所面临的 422 错误。
因此,首先您必须向页面发出请求,获取 cookie 和 csrfToken:
WebClient wc = new WebClient();
string baseSiteString = wc.DownloadString("http://damp-sands-2243.herokuapp.com/students");
string csrfToken = Regex.Match(baseSiteString, "<meta name=\"csrf-token\" content=\"(.*?)\" />").Groups[1].Value;
string cookie = wc.ResponseHeaders[HttpResponseHeader.SetCookie];
Console.WriteLine("Token: {0}", csrfToken);
Console.WriteLine("Cookie: {0}", cookie);
下一部分是提出所有重要的请求headers:
wc.Headers.Add(HttpRequestHeader.Cookie, cookie);
wc.Headers.Add(HttpRequestHeader.ContentType, "application/json; charset=utf-8");
wc.Headers.Add(HttpRequestHeader.Accept, "application/json, text/javascript, */*; q=0.01");
wc.Headers.Add("X-CSRF-Token", csrfToken);
wc.Headers.Add("X-Requested-With", "XMLHttpRequest");
string dataString = @"{""name"":""Meg"",""regi_number"":38}";
byte[] dataBytes = Encoding.UTF8.GetBytes(dataString);
byte[] responseBytes = wc.UploadData(new Uri("https://damp-sands-2243.herokuapp.com/students/"), "POST", dataBytes);
string responseString = Encoding.UTF8.GetString(responseBytes);
Console.WriteLine(responseString);
就是这样:)