C# Web API 在 HTTP Post REST 客户端中发送正文数据
C# Web API Sending Body Data in HTTP Post REST Client
我需要发送这个 HTTP Post 请求:
POST https://webapi.com/baseurl/login
Content-Type: application/json
{"Password":"password",
"AppVersion":"1",
"AppComments":"",
"UserName":"username",
"AppKey":"dakey"
}
它在 RestClient 和 PostMan 中效果很好,就像上面一样。
我需要在语法上有这个,但不确定是否要使用
WebClient、HTTPRequest 或 WebRequest 来完成此操作。
问题是如何格式化正文内容并将其与请求一起发送到上面。
这是我使用 WebClient 示例代码的地方...
private static void Main(string[] args)
{
RunPostAsync();
}
static HttpClient client = new HttpClient();
private static void RunPostAsync(){
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
Inputs inputs = new Inputs();
inputs.Password = "pw";
inputs.AppVersion = "apv";
inputs.AppComments = "apc";
inputs.UserName = "user";
inputs.AppKey = "apk";
var res = client.PostAsync("https://baseuriplus", new StringContent(JsonConvert.SerializeObject(inputs)));
try
{
res.Result.EnsureSuccessStatusCode();
Console.WriteLine("Response " + res.Result.Content.ReadAsStringAsync().Result + Environment.NewLine);
}
catch (Exception ex)
{
Console.WriteLine("Error " + res + " Error " +
ex.ToString());
}
Console.WriteLine("Response: {0}", result);
}
public class Inputs
{
public string Password;
public string AppVersion;
public string AppComments;
public string UserName;
public string AppKey;
}
这现在可以工作并且响应 (200) OK 服务器和响应
你为什么要生成你自己的 json?
使用来自 JsonNewtonsoft 的 JSONConvert
。
您的 json 对象字符串值需要 " "
引号和 ,
我会使用 http 客户端发帖,而不是 webclient。
using (var client = new HttpClient())
{
var res = client.PostAsync("YOUR URL",
new StringContent(JsonConvert.SerializeObject(
new { OBJECT DEF HERE },
Encoding.UTF8, "application/json")
);
try
{
res.Result.EnsureSuccessStatusCode();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
您在发送前没有正确地将您的值序列化为 JSON。与其尝试自己构建字符串,不如使用 JSON.Net.
这样的库
您可以通过执行以下操作获得正确的字符串:
var message = JsonConvert.SerializeObject(new {Password = pw, AppVersion = apv, AppComments = acm, UserName = user, AppKey = apk});
Console.WriteLine(message); //Output: {"Password":"password","AppVersion":"10","AppComments":"","UserName":"username","AppKey":"dakey"}
我们将使用 HttpPost 和 HttpClient PostAsync 来解决这个问题。
using System.Net.Http;
static async Task<string> PostURI(Uri u, HttpContent c)
{
var response = string.Empty;
using (var client = new HttpClient())
{
HttpResponseMessage result = await client.PostAsync(u, c);
if (result.IsSuccessStatusCode)
{
response = result.StatusCode.ToString();
}
}
return response;
}
我们将通过创建一个字符串来调用它 post:
Uri u = new Uri("http://localhost:31404/Api/Customers");
var payload = "{\"CustomerId\": 5,\"CustomerName\": \"Pepsi\"}";
HttpContent c = new StringContent(payload, Encoding.UTF8, "application/json");
var t = Task.Run(() => PostURI(u, c));
t.Wait();
Console.WriteLine(t.Result);
Console.ReadLine();
var client = new RestClient("Your URL");
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("apk-key", apk);
//Serialize to JSON body.
JObject jObjectbody = new JObject();
jObjectbody.Add("employeeName", data.name);
jObjectbody.Add("designation", data.designation);
request.AddParameter("application/json", jObjectbody, ParameterType.RequestBody);
try
{
var clientValue= client.Execute<Response>(request);
return RequestResponse<Response>.Create(ResponseCode.OK, "", clientValue.Data);
}
catch (Exception exception)
{
throw exception;
}
我制作了一个工具来快速轻松地完成它:
Install-Package AdvancedRestHandler
或
dotnet add package AdvancedRestHandler
AdvancedRestHandler arh = new AdvancedRestHandler("https://webapi.com/baseurl");
var result = await arh.PostDataAsync<MyLoginResponse, MyLoginRequest>("/login", new MyLoginRequest{
Password = "password",
AppVersion = "1",
AppComments = "",
UserName = "username",
AppKey = "dakey"
});
public class MyLoginRequest{
public string Password{get;set;}
public string AppVersion{get;set;}
public string AppComments{get;set;}
public string UserName{get;set;}
public string AppKey{get;set;}
}
public class MyLoginResponse {
public string Token{get;set;}
}
额外:
您可以做的另一件事是使用 ArhResponse
:
- 无论哪种方式,在class定义中:
public class MyLoginResponse: ArhResponse
{
...
}
- 或者这样,在 API 调用中:
var result = await arh.PostDataAsync<ArhResponse<MyLoginResponse>, MyLoginRequest> (...)
而不是尝试或缓存,使用简单的 if
语句检查您的 API 调用状态:
// check service response status:
if(result.ResponseStatusCode == HttpStatusCode.OK) { /* api receive success response data */ }
// check Exceptions that may occur due to implementation change, or model errors
if(result.Exception!=null) { /* mostly serializer failed due to model mismatch */ }
// have a copy of request and response, in case the service provider need your request response and they think you are hand writing the service and believe you are wrong
_logger.Warning(result.ResponseText);
_logger.Warning(result.RequestText);
// Get deserialized verion of, one of the fallback models, in case the provider uses more than one type of data in same property of the model
var fallbackData = (MyFallbackResponse)result.FallbackModel;
Header 可能的问题
在某些情况下,由于 HttpClient
生成的 header,服务器不接受 C# 请求。
因为HttpClient默认使用application/json; charset=utf-8
的值作为Content-Type
...
如果只发送application/json
部分作为Content-Type
而忽略; charset=utf-8
部分,您可以按如下方式进行:
对于 HttpClient
,您可以通过查看此线程来修复它:How do you set the Content-Type header for an HttpClient request?
至于 (AdvancedRestHandler) ARH,由于与一些公司的整合,我修复了它,但我不记得完全......我做到了,通过 options
之类的请求或通过重置header
值。
我需要发送这个 HTTP Post 请求:
POST https://webapi.com/baseurl/login
Content-Type: application/json
{"Password":"password",
"AppVersion":"1",
"AppComments":"",
"UserName":"username",
"AppKey":"dakey"
}
它在 RestClient 和 PostMan 中效果很好,就像上面一样。
我需要在语法上有这个,但不确定是否要使用
WebClient、HTTPRequest 或 WebRequest 来完成此操作。
问题是如何格式化正文内容并将其与请求一起发送到上面。
这是我使用 WebClient 示例代码的地方...
private static void Main(string[] args)
{
RunPostAsync();
}
static HttpClient client = new HttpClient();
private static void RunPostAsync(){
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
Inputs inputs = new Inputs();
inputs.Password = "pw";
inputs.AppVersion = "apv";
inputs.AppComments = "apc";
inputs.UserName = "user";
inputs.AppKey = "apk";
var res = client.PostAsync("https://baseuriplus", new StringContent(JsonConvert.SerializeObject(inputs)));
try
{
res.Result.EnsureSuccessStatusCode();
Console.WriteLine("Response " + res.Result.Content.ReadAsStringAsync().Result + Environment.NewLine);
}
catch (Exception ex)
{
Console.WriteLine("Error " + res + " Error " +
ex.ToString());
}
Console.WriteLine("Response: {0}", result);
}
public class Inputs
{
public string Password;
public string AppVersion;
public string AppComments;
public string UserName;
public string AppKey;
}
这现在可以工作并且响应 (200) OK 服务器和响应
你为什么要生成你自己的 json?
使用来自 JsonNewtonsoft 的 JSONConvert
。
您的 json 对象字符串值需要 " "
引号和 ,
我会使用 http 客户端发帖,而不是 webclient。
using (var client = new HttpClient())
{
var res = client.PostAsync("YOUR URL",
new StringContent(JsonConvert.SerializeObject(
new { OBJECT DEF HERE },
Encoding.UTF8, "application/json")
);
try
{
res.Result.EnsureSuccessStatusCode();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
您在发送前没有正确地将您的值序列化为 JSON。与其尝试自己构建字符串,不如使用 JSON.Net.
这样的库您可以通过执行以下操作获得正确的字符串:
var message = JsonConvert.SerializeObject(new {Password = pw, AppVersion = apv, AppComments = acm, UserName = user, AppKey = apk});
Console.WriteLine(message); //Output: {"Password":"password","AppVersion":"10","AppComments":"","UserName":"username","AppKey":"dakey"}
我们将使用 HttpPost 和 HttpClient PostAsync 来解决这个问题。
using System.Net.Http;
static async Task<string> PostURI(Uri u, HttpContent c)
{
var response = string.Empty;
using (var client = new HttpClient())
{
HttpResponseMessage result = await client.PostAsync(u, c);
if (result.IsSuccessStatusCode)
{
response = result.StatusCode.ToString();
}
}
return response;
}
我们将通过创建一个字符串来调用它 post:
Uri u = new Uri("http://localhost:31404/Api/Customers");
var payload = "{\"CustomerId\": 5,\"CustomerName\": \"Pepsi\"}";
HttpContent c = new StringContent(payload, Encoding.UTF8, "application/json");
var t = Task.Run(() => PostURI(u, c));
t.Wait();
Console.WriteLine(t.Result);
Console.ReadLine();
var client = new RestClient("Your URL");
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("apk-key", apk);
//Serialize to JSON body.
JObject jObjectbody = new JObject();
jObjectbody.Add("employeeName", data.name);
jObjectbody.Add("designation", data.designation);
request.AddParameter("application/json", jObjectbody, ParameterType.RequestBody);
try
{
var clientValue= client.Execute<Response>(request);
return RequestResponse<Response>.Create(ResponseCode.OK, "", clientValue.Data);
}
catch (Exception exception)
{
throw exception;
}
我制作了一个工具来快速轻松地完成它:
Install-Package AdvancedRestHandler
或
dotnet add package AdvancedRestHandler
AdvancedRestHandler arh = new AdvancedRestHandler("https://webapi.com/baseurl");
var result = await arh.PostDataAsync<MyLoginResponse, MyLoginRequest>("/login", new MyLoginRequest{
Password = "password",
AppVersion = "1",
AppComments = "",
UserName = "username",
AppKey = "dakey"
});
public class MyLoginRequest{
public string Password{get;set;}
public string AppVersion{get;set;}
public string AppComments{get;set;}
public string UserName{get;set;}
public string AppKey{get;set;}
}
public class MyLoginResponse {
public string Token{get;set;}
}
额外:
您可以做的另一件事是使用 ArhResponse
:
- 无论哪种方式,在class定义中:
public class MyLoginResponse: ArhResponse
{
...
}
- 或者这样,在 API 调用中:
var result = await arh.PostDataAsync<ArhResponse<MyLoginResponse>, MyLoginRequest> (...)
而不是尝试或缓存,使用简单的 if
语句检查您的 API 调用状态:
// check service response status:
if(result.ResponseStatusCode == HttpStatusCode.OK) { /* api receive success response data */ }
// check Exceptions that may occur due to implementation change, or model errors
if(result.Exception!=null) { /* mostly serializer failed due to model mismatch */ }
// have a copy of request and response, in case the service provider need your request response and they think you are hand writing the service and believe you are wrong
_logger.Warning(result.ResponseText);
_logger.Warning(result.RequestText);
// Get deserialized verion of, one of the fallback models, in case the provider uses more than one type of data in same property of the model
var fallbackData = (MyFallbackResponse)result.FallbackModel;
Header 可能的问题
在某些情况下,由于 HttpClient
生成的 header,服务器不接受 C# 请求。
因为HttpClient默认使用application/json; charset=utf-8
的值作为Content-Type
...
如果只发送application/json
部分作为Content-Type
而忽略; charset=utf-8
部分,您可以按如下方式进行:
对于 HttpClient
,您可以通过查看此线程来修复它:How do you set the Content-Type header for an HttpClient request?
至于 (AdvancedRestHandler) ARH,由于与一些公司的整合,我修复了它,但我不记得完全......我做到了,通过 options
之类的请求或通过重置header
值。