为什么增加一个换行符状态说明在ASP.Net关闭连接? [英] Why does adding a newline to StatusDescription in ASP.Net close the connection?
问题描述
当我返回一个状态说明与使用的HTTPStatus codeResult从ASP.Net MVC 3.0换行,我的客户端的连接被强制关闭。应用程序托管在IIS 7.0中。
例如控制器:
公共类FooController的:控制器
{
公众的ActionResult MyAction()
{
返回新的HTTPStatus codeResult((INT)的HTTPStatus code.BadRequest,富\\ n吧);
}
}
例如客户端:
使用(Web客户端的客户端=新的WebClient())
{
client.DownloadString(HTTP://本地主机/应用/美孚/ MyAction);
}
引发的异常:
System.Net.WebException:基础连接已关闭:接收时发生意外错误。
System.IO.IOException:无法读取从传输连接数据:一个现有的连接被强行关闭远程主机。
System.Net.Sockets.SocketException:一个现有的连接被强行关闭远程主机
行为使用curl时是一致的(卷曲7.25.0(I386-PC-win32)中的libcurl / 7.25.0的zlib / 1.2.6)
卷曲的http://本地主机/应用/美孚/ MyAction
块引用>卷曲:(56)recv的失败:连接被重置
修改
最后我用这个自定义的ActionResult,以获得理想的效果。
公共类BadRequestResult:的ActionResult
{
私人const int的错误请求code =(INT)的HTTPStatus code.BadRequest;
私人诠释计数= 0; 公共BadRequestResult(字符串错误)
:这(错误,)
{
} 公共BadRequestResult(字符串格式,params对象[]参数)
{
如果(String.IsNullOrEmpty(格式))
{
抛出新的ArgumentException(格式);
} 错误=的String.Format(格式参数); 数= Errors.Split(新的String [] {} Environment.NewLine,StringSplitOptions.RemoveEmptyEntries)。长度;
} 公共字符串错误{搞定;私人集; } 公共覆盖无效的ExecuteReuslt(ControllerContext上下文)
{
如果(上下文== NULL)
{
抛出新的ArgumentNullException(上下文);
} HTT presponseBase响应= context.HttpContext.Response;
response.TrySkipIisCustomErrors = TRUE;
response.Status code =错误请求code;
response.StatusDescription =的String.Format(错误的请求{0}错误(S),计数);
RESPONSE.WRITE(错误);
到Response.End();
}
}
解决方案您不能在HTTP头中间的断行。
HTTP协议指定报头的末尾是一个换行符。
由于线路中断是在头的中间,头部是不是一个有效的标题和你收到此错误。
修正:不要把换行符在HTTP标头的中间
When I return a StatusDescription with a newline using the HttpStatusCodeResult from ASP.Net MVC 3.0, the connection to my client is forcibly closed. App is hosted in IIS 7.0.
Example controller:
public class FooController : Controller { public ActionResult MyAction() { return new HttpStatusCodeResult((int)HttpStatusCode.BadRequest, "Foo \n Bar"); } }
Example client:
using (WebClient client = new WebClient()) { client.DownloadString("http://localhost/app/Foo/MyAction"); }
Thrown Exception:
System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a receive. System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
The behavior is consistent when using curl (curl 7.25.0 (i386-pc-win32) libcurl/7.25.0 zlib/1.2.6)
curl http://localhost/app/Foo/MyAction
curl: (56) Recv failure: Connection was reset
Edit
I ended up using this custom ActionResult to get the desired results.
public class BadRequestResult : ActionResult { private const int BadRequestCode = (int)HttpStatusCode.BadRequest; private int count = 0; public BadRequestResult(string errors) : this(errors, "") { } public BadRequestResult(string format, params object[] args) { if (String.IsNullOrEmpty(format)) { throw new ArgumentException("format"); } Errors = String.Format(format, args); count = Errors.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries).Length; } public string Errors { get; private set; } public override void ExecuteResult(ControllerContext context) { if (context == null) { throw new ArgumentNullException("context"); } HttpResponseBase response = context.HttpContext.Response; response.TrySkipIisCustomErrors = true; response.StatusCode = BadRequestCode; response.StatusDescription = String.Format("Bad Request {0} Error(s)", count); response.Write(Errors); response.End(); } }
解决方案You can't have a linebreak in the middle of an HTTP header.
The HTTP protocol specifies the end of a header is a line break.
Since the line break is in the middle of a header, the header is not a valid header and you are getting this error.
Fix: Don't put a line break in the middle of an HTTP header.
这篇关于为什么增加一个换行符状态说明在ASP.Net关闭连接?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!