最近我在ASP.NET Core中做了一个中间件CustomizedMiddleware,要说该中间件的功能也很简单,其实就是往HttpResponse中添加一个Cookie而已,但是我将添加Cookie的代码放在了next.Invoke(context)的后面,如下所示:

using Microsoft.AspNetCore.Http;
using System.Threading.Tasks; namespace Assembly.Middlewares
{
public class CustomizedMiddleware
{
private readonly RequestDelegate next; public CustomizedMiddleware(RequestDelegate next)
{
this.next = next;
} public async Task Invoke(Microsoft.AspNetCore.Http.HttpContext context)
{
//Do something...
await next.Invoke(context);
//Do something... context.Response.Cookies.Append("DemoCookie", "DemoValue");//在next.Invoke(context)后添加Cookie到Response
}
}
}

结果代码执行到 context.Response.Cookies.Append("DemoCookie", "DemoValue")时,老是抛出异常。

后来查了查资料,原来HttpResponse中有个很重要的属性HasStarted,HttpResponse.HasStarted属性会返回一个bool类型的值,表示当前Http请求的响应(HttpResponse)是否已经把Http头(Header)的内容发送给客户端浏览器了,如果HttpResponse.HasStarted返回true,我们就不能在HttpResponse上更改任何与Http头(Header)相关的内容了,例如Cookies、Headers、StatusCode等都无法做更改了,否则会抛出异常。此外,当HttpResponse.HasStarted返回true时,如果我们调用HttpResponse.Redirect方法进行跳转,这时HttpResponse.Redirect方法也会抛出异常报错:"System.InvalidOperationException: StatusCode cannot be set because the response has already started.",而且HttpResponse.Redirect不会产生任何效果,客户端浏览器页面也不会进行跳转。

结果我发现当上面的代码执行到context.Response.Cookies.Append("DemoCookie", "DemoValue")时,context.Response.HasStarted已经为true了,所以抛出了异常。

因此我将CustomizedMiddleware中间件的代码改为了如下:

using Microsoft.AspNetCore.Http;
using System.Threading.Tasks; namespace Assembly.Middlewares
{
public class CustomizedMiddleware
{
private readonly RequestDelegate next; public CustomizedMiddleware(RequestDelegate next)
{
this.next = next;
} public async Task Invoke(Microsoft.AspNetCore.Http.HttpContext context)
{
if (!context.Response.HasStarted)//先判断context.Response.HasStarted
{
context.Response.Cookies.Append("DemoCookie", "DemoValue");//在next.Invoke(context)前添加Cookie到Response
} //Do something...
await next.Invoke(context);
//Do something...
}
}
}

这次我把context.Response.Cookies.Append("DemoCookie", "DemoValue")放到了next.Invoke(context)的前面,并做了context.Response.HasStarted的判断,只有当context.Response.HasStarted为false时才添加Cookie,这次就没有抛出异常了,而且context.Response.Cookies.Append("DemoCookie", "DemoValue")也成功添加了Cookie到HttpResponse中。

所以这里总结下在ASP.NET Core的中间件中,尽量在next.Invoke(context)调用前做Response.Cookies和Response.Headers等属性的修改,修改前还要判断Response.HasStarted的值,如果是true,就不能做任何修改了。

ASP.NET Core中如果Response.HasStarted已经为true,就不能更改Response.Cookies和Response.Headers等属性的值了的更多相关文章

  1. ASP.NET Core中显示自定义错误页面-增强版

    之前的博文 ASP.NET Core中显示自定义错误页面 中的方法是在项目中硬编码实现的,当有多个项目时,就会造成不同项目之间的重复代码,不可取. 在这篇博文中改用middleware实现,并且放在独 ...

  2. ASP.NET Core中使用Graylog记录日志

    以下基于.NET Core 2.1 定义GrayLog日志记录中间件: 中间件代码: public class GrayLogMiddleware { private readonly Request ...

  3. ASP.NET Core 中 HttpContext 详解与使用 | Microsoft.AspNetCore.Http 详解 (转载)

    “传导体” HttpContext 要理解 HttpContext 是干嘛的,首先,看图 图一 内网访问程序 图二 反向代理访问程序 ASP.NET Core 程序中,Kestrel 是一个基于 li ...

  4. ASP.NET Core 中 HttpContext 详解与使用 | Microsoft.AspNetCore.Http 详解

    笔者没有学 ASP.NET,直接学 ASP.NET Core ,学完 ASP.NET Core MVC 基础后,开始学习 ASP.NET Core 的运行原理.发现应用程序有一个非常主要的 “传导体” ...

  5. 在ASP.NET Core中使用百度在线编辑器UEditor

    在ASP.NET Core中使用百度在线编辑器UEditor 0x00 起因 最近需要一个在线编辑器,之前听人说过百度的UEditor不错,去官网下了一个.不过服务端只有ASP.NET版的,如果是为了 ...

  6. ASP.NET Core 中文文档 第三章 原理(6)全球化与本地化

    原文:Globalization and localization 作者:Rick Anderson.Damien Bowden.Bart Calixto.Nadeem Afana 翻译:谢炀(Kil ...

  7. ASP.NET Core 中文文档 第三章 原理(13)管理应用程序状态

    原文:Managing Application State 作者:Steve Smith 翻译:姚阿勇(Dr.Yao) 校对:高嵩 在 ASP.NET Core 中,有多种途径可以对应用程序的状态进行 ...

  8. 在ASP.NET Core中使用Angular2,以及与Angular2的Token base身份认证

    注:下载本文提到的完整代码示例请访问:How to authorization Angular 2 app with asp.net core web api 在ASP.NET Core中使用Angu ...

  9. 如何在ASP.NET Core中实现CORS跨域

    注:下载本文的完整代码示例请访问 > How to enable CORS(Cross-origin resource sharing) in ASP.NET Core 如何在ASP.NET C ...

随机推荐

  1. loadsh常用函数

    此篇文章会记录常用的lodash函数 防抖函数:_.debounce() 创建一个去缓冲函数,该函数将自上次调用函数以来经过设置的等待毫秒后调用func. 去缓冲函数带有一个取消方法来取消延迟的fun ...

  2. 腾讯Tars环境搭建 ---- centos

    1,安装git yum install git 2,下载脚本 git clone https://github.com/tangramor/Tars_Install.git 注意:会有3个脚本,cen ...

  3. Linux 学习笔记之超详细基础linux命令(the end)

    Linux学习笔记之超详细基础linux命令 by:授客 QQ:1033553122 ---------------------------------接Part 14---------------- ...

  4. U8 应付款管理 单据类型 分析

    Ap_CloseBill   收付款单主表 Ap_CloseBills 收付款单子表 cVouchType 在收付款单主表中  ,用于区分单据为收款单还是付款单(48,49)  49:付款单 48:收 ...

  5. 安卓开发----TextView控件属性列表(转)

    文章原地址: http://wwzcraig.blog.163.com/blog/static/64622969201373184343118/ android:autoLink设置是否当文本为URL ...

  6. 洗礼灵魂,修炼python(38)--面向对象编程(8)—从算术运算符进一步认识魔法方法

    上一篇文章了解了魔法方法,相信你已经归魔法方法至少有个概念了,那么今天就进一步的认识魔法方法.说这个之前,大脑里先回忆一下算术操作符. 什么是算术操作符?忘记没有?忘记了的自己倒回去看我前面的博文或者 ...

  7. 【HANA系列】SAP HANA XS的JavaScript安全事项

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列]SAP HANA XS使用Jav ...

  8. HTML 5 <input> list 属性

    定义和用法 list 属性引用数据列表,其中包含输入字段的预定义选项. 可以用来做关联搜素

  9. plsql developer如何查询SQL语句执行历史记录(转)

    相信很多在plsql developer调试oracle的朋友,经常会遇到在plsql developer执行的某一条SQL语句没有保存,那么我们在plsql developer下如何找到我们执行过的 ...

  10. oracle经验记录

    1.添加新User时必须要增加的角色权限:connect.dba.resource 2.添加表空间的语句 create tablespace DEMOSPACE datafile 'D:/test.d ...