ASP.NET 的Request 物件的生命周期很短,只会出现在一个Http Request,当需要跨物件传递资料时,比如HttpModule、HttpHandler、Page 、Controller,可以善用Request 物件来存放短暂的状态。
既然可以传递物件,那么我们也可以在Request 初始化的时候,将所需要的物件注入至Request 里面,然后再到到Page / Controller 取出来用;在不同的专案范本可以使用的Request 物件都不太一样,接下来分享我已经知道的写法。
开发环境
VS IDE 2019
IIS主机ASP.NET 4.8 WebForm / MVC5 / Web API
OWIN主机Web API
ASP.NET Core 3.1
存放状态的方式是key-value,型别为IDictionary or IDictionary<string,object>
System.Web.HttpContext.Items
.NET 2.0的时代用HttpContext.Items (IDictionary Type),到了.NET 3.5之后可以改用HttpContextBase.Items。
HttpContextWrapper则是用来把HttpContext变成HttpContextBase。
HttpContextBase是一个抽象,可以让我们更好测试 [Unit Test]使用HttpContextBase取代HttpContext.Current,提高可测试性
HttpContext.Items 是IDictionary型别,Key对应Object。
适用ASP.NET WebForm、ASP.NET MVC。
从Global.asax注入Member物件至 HttpContext.Items
public class Global : HttpApplication{ protected void Application_BeginRequest() { var member = new Member {Id = Guid.NewGuid(), Name = Name.FullName()}; var key = member.GetType().FullName; HttpContext.Current.Items[key] = member; }}
在Default.aspx.cs取出,这里我用了HttpContextWrapper把HttpContext转成HttpContextBase
public partial class Default : Page{ protected void Page_Load(object sender, EventArgs e) { if (this.IsPostBack) { return; } var httpContext = new HttpContextWrapper(HttpContext.Current); var key = typeof(Member).FullName; var member = httpContext.Items[key] as Member; this.Id_Label.Text = member.Id.ToString(); this.Name_Label.Text = member.Name; }}
System.Web.HttpContextBase.Items
Controller 依赖HttpContextBase 非HttpContext
适用ASP.NET MVC5
在 ActionFilterAttribute 注入 Member 物件至 HttpContextBase.Items
public class InjectionAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { //初始化物件 var member = new Member {Id = Guid.NewGuid(), Name =Faker.Name.FullName()}; var key = member.GetType().FullName; //注入到 HttpContextBase filterContext.RequestContext.HttpContext.Items[key] = member; } }
在 Controller 取出 Member 物件
public class HomeController : Controller { // GET: Default public ActionResult Index() { var key = typeof(Member).FullName; var member = this.HttpContext.Items[key]; return View(member); } }
System.Net.Http.HttpRequestMessage.Properties
HttpRequestMessage.Properties [“ key”] 是IDictionary <string,object>型别
适用的ASP.NET Web API / ASP.NET Core Web API
在 ActionFilterAttribute 注入 Member 物件至 HttpRequestMessage.Properties["key"]
public class InjectionAttribute : ActionFilterAttribute { public override void OnActionExecuting(HttpActionContext filterContext) { //初始化物件 var member = new Member {Id = Guid.NewGuid(), Name = Faker.Name.FullName()}; var key = member.GetType().FullName; //注入到 HttpRequestMessage filterContext.Request.Properties[key] = member; } }
在 ApiController 取出 Member 物件
public class DefaultController : ApiController { // GET: api/Default public IHttpActionResult Get() { var key = typeof(Member).FullName; var member = this.Request.Properties[key] as Member; return this.Ok(member); } }
Microsoft.Owin.IOwinContext.Environment
IOwinContext.Environment 是IDictionary<string,object>型别
IOwinContext.Set/Get骨子里面是控制IOwinContext.Environment
适用OWIN
app.Use Middleware 注入 Member 物件至 IOwinContext.Environment["key"]
public class Startup { public void Configuration(IAppBuilder app) { var config = new HttpConfiguration(); // Web API configuration and services // Web API routes config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{id}", new {id = RouteParameter.Optional} ); app.Use(async (owinContext, next) => { var member = new Member { Id = Guid.NewGuid(), Name = Name.FullName() }; //owinContext.Set(member.GetType().FullName, member); owinContext.Environment[member.GetType().FullName] = member; await next(); }); app.UseErrorPage() .UseWebApi(config); } }
在 ApiController ,用 IOwinContext.Get 取出 Member 物件
public class DefaultController : ApiController { // GET: api/Default public IHttpActionResult Get() { var key = typeof(Member).FullName; var member = this.Request.GetOwinContext().Get<Member>(key); return this.Ok(member); } }
Microsoft.AspNetCore.Http.HttpContext.Items
HttpContext.Items 是IDictionary<object,object>型别
适用ASP.NET Core
app.Use Middleware 注入 Member 物件至 HttpContext.Items
public class Startup { public IConfiguration Configuration { get; } public Startup(IConfiguration configuration) { this.Configuration = configuration; } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.Use(async (owinContext, next) => { var member = new Member { Id = Guid.NewGuid(), Name = Faker.Name.FullName() }; var key = member.GetType().FullName; owinContext.Items[key] = member; await next(); }); app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddControllers(); } }
在 Controller 用 HttpContext.Items 取出 Member
[ApiController] [Route("api/[controller]")] public class DefaultController : ControllerBase { [HttpGet] public async Task<ActionResult<Member>> Get() { var key = typeof(Member).FullName; var member = this.HttpContext.Items[key] as Member; return this.Ok(member); } }
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。