使用 C# HttpClient 重写 Java HttpURLConnection 方法
Rewriting a Java HttpURLConnection method using C# HttpClient
我有一个使用 java.net.HttpURLConnection 的有效 Java 方法,我应该使用 .NET HttpClient 在 C# 中重新实现它。
Java方法:
public static String getMyThingAPIToken() throws IOException{
URL apiURL = new URL("https://myThingAPI/token");
HttpURLConnection apiConnection = (HttpURLConnection) apiURL.openConnection();
apiConnection.setRequestMethod("POST");
apiConnection.setDoOutput(true);
String apiBodyString = "myThingAPI login id and secret key";
byte[] apiBody = apiBodyString.getBytes(StandardCharsets.UTF_8);
OutputStream apiBodyStream = apiConnection.getOutputStream();
apiBodyStream.write(apiBody);
StringBuffer apiResponseBuffer;
try (BufferedReader in = new BufferedReader(new InputStreamReader(apiConnection.getInputStream()))){
String inputline;
apiResponseBuffer = new StringBuffer();
while((inputline = in.readLine()) != null) {
apiResponseBuffer.append(inputline);
}
}
}
到目前为止,我的 C# 如下所示,您会注意到我的这种早期实现形式不会解释响应。它也没有令牌字符串所需的字符串 return 类型。
这是因为我测试的时候,响应有:
状态码:400
ReasonPhrase: 'Bad Request'
所以我的 apiBody 字节数组中的某些内容或 PostAsync 的使用必须与 Java 方法所做的不同,但我无法弄清楚它可能是什么。
public async static Task<HttpResponseMessage> getMyThingAPIToken(HttpClient client)
{
var apiURI = new Uri("https://myThingAPI/token");
string apiBodystring = "myThingAPI login id and secret key";
byte[] apiBody = System.Text.Encoding.UTF8.GetBytes(apiBodystring);
var response = await client.PostAsync(apiURI, new ByteArrayContent(apiBody));
return response;
}
您可以尝试使用以下代码吗:
client.BaseAddress = new Uri("https://myThingAPI/");
var message = new HttpRequestMessage(HttpMethod.Post, "/token");
// Add your login id and secret key here with the format you want to send
message.Content = new StringContent(string.Format("userName={0}&password={1}", UserName, Password));
var result = await client.SendAsync(message);
return result;
Java 代码未指定类型,这意味着 by default 请求使用 application/x-www-form-urlencoded
。这用于 FORM POST 请求。
另一方面,ByteArrayContent
的默认内容类型是 application/octet-stream
,而 StringContent
的默认内容类型是 text/plain
。
FORM 内容通过 FormUrlEncoodedContent class 使用,它可以接受任何 Dictionary<string,string>
作为有效负载。
问题中的输入 不是 的 x-www-form-urlencoded
形式,所以它不是真正的内容,或者 API 滥用了内容类型。
假设 API 接受适当的 x-www-form-urlencoded
内容,以下应该有效:
var data=new Dictionary<string,string>{
["login"]=....,
["secret"]=.....,
["someOtherField"]=....
};
var content= new FormUrlEncodedContent(data);
var response=await client.PostAsync(apiURI,content);
要使用 application/x-www-form-urlencoded
发送任何文本,我们需要在 StringContent's constructor 中指定内容类型:
var contentType="application/x-www-form-urlencoded";
var content= new StringContent(apiBodyString, Encoding.UTF8,contentType);
var response=await client.PostAsync(apiURI,content);
我有一个使用 java.net.HttpURLConnection 的有效 Java 方法,我应该使用 .NET HttpClient 在 C# 中重新实现它。
Java方法:
public static String getMyThingAPIToken() throws IOException{
URL apiURL = new URL("https://myThingAPI/token");
HttpURLConnection apiConnection = (HttpURLConnection) apiURL.openConnection();
apiConnection.setRequestMethod("POST");
apiConnection.setDoOutput(true);
String apiBodyString = "myThingAPI login id and secret key";
byte[] apiBody = apiBodyString.getBytes(StandardCharsets.UTF_8);
OutputStream apiBodyStream = apiConnection.getOutputStream();
apiBodyStream.write(apiBody);
StringBuffer apiResponseBuffer;
try (BufferedReader in = new BufferedReader(new InputStreamReader(apiConnection.getInputStream()))){
String inputline;
apiResponseBuffer = new StringBuffer();
while((inputline = in.readLine()) != null) {
apiResponseBuffer.append(inputline);
}
}
}
到目前为止,我的 C# 如下所示,您会注意到我的这种早期实现形式不会解释响应。它也没有令牌字符串所需的字符串 return 类型。
这是因为我测试的时候,响应有: 状态码:400 ReasonPhrase: 'Bad Request'
所以我的 apiBody 字节数组中的某些内容或 PostAsync 的使用必须与 Java 方法所做的不同,但我无法弄清楚它可能是什么。
public async static Task<HttpResponseMessage> getMyThingAPIToken(HttpClient client)
{
var apiURI = new Uri("https://myThingAPI/token");
string apiBodystring = "myThingAPI login id and secret key";
byte[] apiBody = System.Text.Encoding.UTF8.GetBytes(apiBodystring);
var response = await client.PostAsync(apiURI, new ByteArrayContent(apiBody));
return response;
}
您可以尝试使用以下代码吗:
client.BaseAddress = new Uri("https://myThingAPI/");
var message = new HttpRequestMessage(HttpMethod.Post, "/token");
// Add your login id and secret key here with the format you want to send
message.Content = new StringContent(string.Format("userName={0}&password={1}", UserName, Password));
var result = await client.SendAsync(message);
return result;
Java 代码未指定类型,这意味着 by default 请求使用 application/x-www-form-urlencoded
。这用于 FORM POST 请求。
另一方面,ByteArrayContent
的默认内容类型是 application/octet-stream
,而 StringContent
的默认内容类型是 text/plain
。
FORM 内容通过 FormUrlEncoodedContent class 使用,它可以接受任何 Dictionary<string,string>
作为有效负载。
问题中的输入 不是 的 x-www-form-urlencoded
形式,所以它不是真正的内容,或者 API 滥用了内容类型。
假设 API 接受适当的 x-www-form-urlencoded
内容,以下应该有效:
var data=new Dictionary<string,string>{
["login"]=....,
["secret"]=.....,
["someOtherField"]=....
};
var content= new FormUrlEncodedContent(data);
var response=await client.PostAsync(apiURI,content);
要使用 application/x-www-form-urlencoded
发送任何文本,我们需要在 StringContent's constructor 中指定内容类型:
var contentType="application/x-www-form-urlencoded";
var content= new StringContent(apiBodyString, Encoding.UTF8,contentType);
var response=await client.PostAsync(apiURI,content);