ASP.NET Core MVC 从入门到精通之HttpContext
原文链接:https://www.cnblogs.com/hsiang/p/17368101.html
什么是HttpContext?
在B/S模式开发的程序中,客户端是浏览器,服务器端Web服务程序,HttpContext是连接客户端和服务器端程序的桥梁,交代了当前请求的环境信息,它封装了请求[Request]和响应[Response]及其他所有信息,示意图如下所示:
图一 内网访问程序

图二 反向代理访问程序

在示意图中,Kestrel 是一个基于 libuv 的跨平台ASP.NET Core web服务器。不清楚 Kerstrel 没关系,以后慢慢了解。
注意:HttpContext从客户端发起一个请求开始,到服务器端响应完成结束,每一个新的请求,都会创建一个新的HttpContext对象。
HttpContext属性
在HttpContext中,最常用的属性有3个【Request,Response,Session】具体属性如下表所示:

控制器中应用HttpContext
在控制器中,HttpContext作为控制器父类ControllerBase的属性存在,且Request和Response作为使用频率非常高的常用对像,控制器也声明成了属性,都可以直接使用。如下所示:

控制器外使用HttpContext
在应用程序中,控制器继承了Controller类,所以才能不用声明就可以直接使用HttpContext,但是除了控制器,还在其他的程序,那在其他程序中,如何使用HttpContext呢?
首先有一个服务接口IStudentService和服务实现类StudentService,其他中在StudentService中访问HttpContext,如下所示:
namespace DemoCoreMVC.Services
{
public interface IStudentService
{
/// <summary>
/// 保存类
/// </summary>
void Save();
}
}
namespace DemoCoreMVC.Services
{
public class StudentService : IStudentService
{
private readonly IHttpContextAccessor contextAccessor;
public StudentService(IHttpContextAccessor contextAccessor)
{
this.contextAccessor = contextAccessor;
}
public void Save()
{
var name = this.contextAccessor.HttpContext?.Request.Query["Name"];
Console.WriteLine(name);
}
}
}
在控制器中,通过构造函数的方式将IStudentService注入进去,如下所示:
using DemoCoreMVC.Services;
using Microsoft.AspNetCore.Mvc;
namespace DemoCoreMVC.Controllers
{
public class StudentController : Controller
{
private readonly IStudentService studentService;
public StudentController(IStudentService studentService)
{
this.studentService = studentService;
}
public IActionResult Save()
{
studentService.Save();
return Json("成功");
}
public IActionResult Index()
{
return View();
}
}
}
在Program.cs中,将服务添加到容器中,如下所示:
1 //增加一个默认的HttpContextAccessor 2 builder.Services.AddHttpContextAccessor(); 3 //增加服务 4 builder.Services.AddScoped<IStudentService, StudentService>();
经过以上3步,就可以实现在控制器之外的类中,访问HttpContext,测试示例,如下所示:

注意:在ASP.NET Core MVC项目中,对象的创建,优先从容器中获取,这样可以不需要考虑它的创建过程和构造参数。如:创建服务Service,控制器对象Controller,视图对象View,数据访问层Repository等内容。对于模型对象,如视图模型,数据模型等不依赖其他对象的类型,则可以通过New进行创建。
HttpRequest
HttpRequest表示单个请求的传入端,常用的Query用于获取Get请求传递的参数,Form用于获取Post请求传递的参数,如下所示:

HttpRequest示例
在本示例中,以Request.Form为例,获取Post方式传递的参数,客户端将所有需要传递的内容包括在Form表单内容,在服务器端Action中通过Request.Form["Key"]进行获取。如下所示:
Add.cshtml视图中Form表单内容,如下所示:
<form action="~/Hello/Save" method="post">
<div style="margin:10px;">
<span>学号:</span>
<input type="text" name="Id" />
</div>
<div style="margin:10px;">
<span>姓名:</span>
<input type="text" name="Name" />
</div style="margin:10px;">
<div style="margin:10px;">
<span>年龄:</span>
<input type="text" name="Age" />
</div>
<div style="margin:10px;">
<span>性别:</span>
<input type="text" name="Sex" />
</div>
<div style="margin:10px;">
<input type="submit" name="submit" value="保存" />
</div>
</form>
HelloController中Save方法,如下所示:
[HttpPost]
public IActionResult Save()
{
var id = Request.Form["Id"];
var name = Request.Form["Name"];
var age = Request.Form["Age"];
var sex = Request.Form["Sex"];
var student = new Student()
{
Id = string.IsNullOrEmpty(id) ? 0 : int.Parse(id),
Name = name,
Age = string.IsNullOrEmpty(age) ? 0 : int.Parse(age),
Sex = sex
};
return Json(student);
}
运行测试,在浏览器中输入网址【https://localhost:7116/Hello/add】进行测试,如下所示:

HttpRequest其它示例
HttpRequest中的其它示例,如下所示:
public IActionResult Index()
{
Console.WriteLine($"Request.Host:{Request.Host}" );
Console.WriteLine($"Request.Path:{Request.Path}");
Console.WriteLine($"Request.Protocol:{Request.Protocol}");
Console.WriteLine($"Request.ContentType:{Request.ContentType}");
Console.WriteLine($"Request.Headers:");
foreach(var header in Request.Headers)
{
Console.WriteLine($"{header.Key}:{header.Value}");
}
Console.WriteLine($"Request.Cookies:");
foreach (var cookie in Request.Cookies)
{
Console.WriteLine($"{cookie.Key}:{cookie.Value}");
}
return View();
}
其它属性示例截图,如下所示:

意:在Request的Get请求中,默认ContentType为空,Cookies如果没有设置,也为空。
Cookie存放于客户端浏览器中,可以通过浏览器开发者模式F12下进行查看,以www.bilibili.com为例,如下所示:
浙公网安备 33010602011771号