一、原理讲解
1. http调用的基本原理
http调用本质上是:
- 客户端(你的c#程序)向服务器通过网络发送http请求(如get、post等),
- 服务器接收请求并处理,
- 然后把响应(数据、状态码等)返回给客户端。
在c#中,最常用的http调用类库是 httpclient(.net framework 4.5+自带),它封装了底层的socket通信和http协议细节,使开发者可以更简单地发起网络请求。
2. 主要流程
- 建立连接:
httpclient内部通过tcp协议与目标服务器建立连接(通常通过socket)。 - 发送请求:构造http请求报文(包括请求行、请求头、请求体)。
- 等待响应:服务器返回http响应报文(包括响应行、响应头、响应体)。
- 读取响应:
httpclient读取响应内容,供程序处理。 - 关闭连接:连接可以复用(keep-alive),也可关闭。
3. 底层原理简述
httpclient基于httpwebrequest/httpwebresponse(.net core和.net 5+底层有优化)。- 网络通信实际是通过socket进行数据收发。
- http协议规定了请求和响应的格式,
httpclient负责封装和解析。
4. 代码示例与报文结构
以get请求为例:
代码
using system;
using system.net.http;
using system.threading.tasks;
class program
{
public static async task main(string[] args)
{
using (httpclient client = new httpclient())
{
httpresponsemessage response = await client.getasync("https://jsonplaceholder.typicode.com/posts/1");
string content = await response.content.readasstringasync();
console.writeline(content);
}
}
}实际http报文
请求报文:
get /posts/1 http/1.1 host: jsonplaceholder.typicode.com user-agent: ... accept: ... connection: keep-alive ...
响应报文:
http/1.1 200 ok
content-type: application/json; charset=utf-8
content-length: 292
...
{
"userid": 1,
"id": 1,
"title": "...",
"body": "..."
}
5. 关键点
- 请求方式:决定http请求的类型(get/post/put/delete等)。
- 请求头/响应头:包含元数据(如content-type、authorization等)。
- 请求体/响应体:实际传输的数据(如json、文本、文件等)。
- 状态码:服务器响应的处理结果(如200、404、500等)。
6. 总结
- c#通过
httpclient等类库,底层用socket实现http协议的数据收发。 httpclient负责封装http报文,简化开发流程。- http调用的本质是:构造请求 → 发送 → 等待响应 → 解析响应。
二、完整代码示例
1. 引入命名空间
using system; using system.net.http; using system.text; using system.threading.tasks;
2. get请求
public static async task httpgetasync()
{
using (httpclient client = new httpclient())
{
// 设置请求头(可选)
client.defaultrequestheaders.add("user-agent", "c# app");
// 发送get请求
httpresponsemessage response = await client.getasync("https://jsonplaceholder.typicode.com/posts/1");
// 判断是否成功
if (response.issuccessstatuscode)
{
string content = await response.content.readasstringasync();
console.writeline("get请求结果:");
console.writeline(content);
}
else
{
console.writeline($"get请求失败,状态码:{response.statuscode}");
}
}
}3. post请求(发送json)
public static async task httppostasync()
{
using (httpclient client = new httpclient())
{
// 构造要发送的数据
string json = "{\"title\": \"foo\", \"body\": \"bar\", \"userid\": 1}";
stringcontent content = new stringcontent(json, encoding.utf8, "application/json");
// 发送post请求
httpresponsemessage response = await client.postasync("https://jsonplaceholder.typicode.com/posts", content);
// 判断是否成功
if (response.issuccessstatuscode)
{
string result = await response.content.readasstringasync();
console.writeline("post请求结果:");
console.writeline(result);
}
else
{
console.writeline($"post请求失败,状态码:{response.statuscode}");
}
}
}4. 主函数调用示例
public static async task main(string[] args)
{
await httpgetasync();
await httppostasync();
}5. 完整代码示例
using system;
using system.net.http;
using system.text;
using system.threading.tasks;
class program
{
public static async task httpgetasync()
{
using (httpclient client = new httpclient())
{
client.defaultrequestheaders.add("user-agent", "c# app");
httpresponsemessage response = await client.getasync("https://jsonplaceholder.typicode.com/posts/1");
if (response.issuccessstatuscode)
{
string content = await response.content.readasstringasync();
console.writeline("get请求结果:");
console.writeline(content);
}
else
{
console.writeline($"get请求失败,状态码:{response.statuscode}");
}
}
}
public static async task httppostasync()
{
using (httpclient client = new httpclient())
{
string json = "{\"title\": \"foo\", \"body\": \"bar\", \"userid\": 1}";
stringcontent content = new stringcontent(json, encoding.utf8, "application/json");
httpresponsemessage response = await client.postasync("https://jsonplaceholder.typicode.com/posts", content);
if (response.issuccessstatuscode)
{
string result = await response.content.readasstringasync();
console.writeline("post请求结果:");
console.writeline(result);
}
else
{
console.writeline($"post请求失败,状态码:{response.statuscode}");
}
}
}
public static async task main(string[] args)
{
await httpgetasync();
await httppostasync();
}
}6. 添加自定义请求头(如token)
public static async task httpgetwithtokenasync()
{
using (httpclient client = new httpclient())
{
// 添加bearer token
client.defaultrequestheaders.authorization = new system.net.http.headers.authenticationheadervalue("bearer", "your_token_here");
httpresponsemessage response = await client.getasync("https://api.example.com/data");
string result = await response.content.readasstringasync();
console.writeline(result);
}
}7. 发送表单数据(application/x-www-form-urlencoded)
public static async task httppostformasync()
{
using (httpclient client = new httpclient())
{
var formdata = new formurlencodedcontent(new[]
{
new keyvaluepair<string, string>("username", "test"),
new keyvaluepair<string, string>("password", "123456")
});
httpresponsemessage response = await client.postasync("https://httpbin.org/post", formdata);
string result = await response.content.readasstringasync();
console.writeline(result);
}
}8. 上传文件(multipart/form-data)
public static async task httppostfileasync()
{
using (httpclient client = new httpclient())
{
using (var multipartformcontent = new multipartformdatacontent())
{
// 添加文件
var filestream = system.io.file.openread("test.txt");
multipartformcontent.add(new streamcontent(filestream), name: "file", filename: "test.txt");
// 添加其他表单字段
multipartformcontent.add(new stringcontent("value1"), "field1");
httpresponsemessage response = await client.postasync("https://httpbin.org/post", multipartformcontent);
string result = await response.content.readasstringasync();
console.writeline(result);
}
}
}9. 设置超时和异常处理
public static async task httpgetwithtimeoutasync()
{
using (httpclient client = new httpclient())
{
client.timeout = timespan.fromseconds(5); // 设置超时时间
try
{
httpresponsemessage response = await client.getasync("https://jsonplaceholder.typicode.com/posts/1");
string content = await response.content.readasstringasync();
console.writeline(content);
}
catch (taskcanceledexception ex)
{
console.writeline("请求超时: " + ex.message);
}
catch (exception ex)
{
console.writeline("请求异常: " + ex.message);
}
}
}10. 反序列化json响应为对象
你可以使用 system.text.json 或 newtonsoft.json,这里用自带的 system.text.json。
using system.text.json;
public class post
{
public int userid { get; set; }
public int id { get; set; }
public string title { get; set; }
public string body { get; set; }
}
public static async task httpgetdeserializeasync()
{
using (httpclient client = new httpclient())
{
httpresponsemessage response = await client.getasync("https://jsonplaceholder.typicode.com/posts/1");
string content = await response.content.readasstringasync();
// 反序列化为对象
var post = jsonserializer.deserialize<post>(content);
console.writeline($"标题: {post.title}, 内容: {post.body}");
}
}到此这篇关于c# http调用详细代码的文章就介绍到这了,更多相关c# http调用内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论