ASP.NET Web Api HttpResponseException 400 (Bad Request) 被 IIS 劫持

Posted

技术标签:

【中文标题】ASP.NET Web Api HttpResponseException 400 (Bad Request) 被 IIS 劫持【英文标题】:ASP.NET Web Api HttpResponseException 400 (Bad Request) Hijacked by IIS 【发布时间】:2012-04-02 23:44:42 【问题描述】:

如果我的 ModelState 无效,我正在编写 Web API 服务并尝试返回 (400) 错误请求。我不希望将响应主体附加到此。似乎 IIS 正在劫持我的响应,并且总是返回带有冗长样式错误页面的 text/html 内容类型。这是个问题。

    [HttpPost]
    public void Link(LinkDeviceModel model)
    

        if (ModelState.IsValid)
        
            try
            
                model.Save();
            
            catch (Exception ex)
            
                ErrorSignal.FromCurrentContext().Raise(ex);
                throw new HttpResponseException(ex.Message, HttpStatusCode.InternalServerError);
            
        
        else
        
            throw new HttpResponseException(HttpStatusCode.BadRequest);
        
    

这是我的提琴手请求:

POST http://localhost/myapp/service/link HTTP/1.1
Host: localhost
Content-Length: 112
Content-Type: application/json
Accept: application/json

"DeviceUniqueId":"CC9C6FC0-7D06-11E1-8B0E-31564824019B", "UserName": "me@mycompany.com"," Pin": "111111"

而我的反应是错误的,充满了身体,反应:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<title>IIS 7.5 Detailed Error - 400.0 - Bad Request</title> 
<style type="text/css"> 
<!-- 
bodymargin:0;font-size:.7em;font-family:Verdana,Arial,Helvetica,sans-serif;background:#CBE1EF; 
codemargin:0;color:#006600;font-size:1.1em;font-weight:bold; 
.config_source codefont-size:.8em;color:#000000; 
premargin:0;font-size:1.4em;word-wrap:break-word; 
ul,olmargin:10px 0 10px 40px; 
ul.first,ol.firstmargin-top:5px; 
fieldsetpadding:0 15px 10px 15px; 
.summary-container fieldsetpadding-bottom:5px;margin-top:4px; 
legend.no-expand-allpadding:2px 15px 4px 10px;margin:0 0 0 -12px; 
legendcolor:#333333;padding:4px 15px 4px 10px;margin:4px 0 8px -12px;_margin-top:0px; 
 border-top:1px solid #EDEDED;border-left:1px solid #EDEDED;border-right:1px solid #969696; 
 border-bottom:1px solid #969696;background:#E7ECF0;font-weight:bold;font-size:1em; 
a:link,a:visitedcolor:#007EFF;font-weight:bold; 
a:hovertext-decoration:none; 
h1font-size:2.4em;margin:0;color:#FFF; 
h2font-size:1.7em;margin:0;color:#CC0000; 
h3font-size:1.4em;margin:10px 0 0 0;color:#CC0000; 
h4font-size:1.2em;margin:10px 0 5px 0; 
#headerwidth:96%;margin:0 0 0 0;padding:6px 2% 6px 2%;font-family:"trebuchet MS",Verdana,sans-serif; 
 color:#FFF;background-color:#5C87B2; 
#contentmargin:0 0 0 2%;position:relative; 
.summary-container,.content-containerbackground:#FFF;width:96%;margin-top:8px;padding:10px;position:relative; 
.config_sourcebackground:#fff5c4; 
.content-container pmargin:0 0 10px 0; 
#details-leftwidth:35%;float:left;margin-right:2%; 
#details-rightwidth:63%;float:left;overflow:hidden; 
#server_versionwidth:96%;_height:1px;min-height:1px;margin:0 0 5px 0;padding:11px 2% 8px 2%;color:#FFFFFF; 
 background-color:#5A7FA5;border-bottom:1px solid #C1CFDD;border-top:1px solid #4A6C8E;font-weight:normal; 
 font-size:1em;color:#FFF;text-align:right; 
#server_version pmargin:5px 0; 
tablemargin:4px 0 4px 0;width:100%;border:none; 
td,thvertical-align:top;padding:3px 0;text-align:left;font-weight:bold;border:none; 
thwidth:30%;text-align:right;padding-right:2%;font-weight:normal; 
thead thbackground-color:#ebebeb;width:25%; 
#details-right thwidth:20%; 
table tr.alt td,table tr.alt thbackground-color:#ebebeb; 
.highlight-codecolor:#CC0000;font-weight:bold;font-style:italic; 
.clearclear:both; 
.preferredpadding:0 5px 2px 5px;font-weight:normal;background:#006633;color:#FFF;font-size:.8em; 
--> 
</style> 

</head> 
<body> 
<div id="header"><h1>Server Error in Application "DEFAULT WEB SITE/MYAPP"</h1></div> 
<div id="server_version"><p>Internet Information Services 7.5</p></div> 
<div id="content"> 
<div class="content-container"> 
 <fieldset><legend>Error Summary</legend> 
  <h2>HTTP Error 400.0 - Bad Request</h2> 
  <h3>Bad Request</h3> 
 </fieldset> 
</div> 
<div class="content-container"> 
 <fieldset><legend>Detailed Error Information</legend> 
  <div id="details-left"> 
   <table border="0" cellpadding="0" cellspacing="0"> 
    <tr class="alt"><th>Module</th><td>ManagedPipelineHandler</td></tr> 
    <tr><th>Notification</th><td>ExecuteRequestHandler</td></tr> 
    <tr class="alt"><th>Handler</th><td>System.Web.Http.WebHost.HttpControllerHandler</td></tr> 
    <tr><th>Error Code</th><td>0x00000000</td></tr> 

   </table> 
  </div> 
  <div id="details-right"> 
   <table border="0" cellpadding="0" cellspacing="0"> 
    <tr class="alt"><th>Requested URL</th><td>http://localhost:80/myapp/service/link</td></tr> 
    <tr><th>Physical Path</th><td>C:\workspace\myapp\service\link</td></tr> 
    <tr class="alt"><th>Logon Method</th><td>Anonymous</td></tr> 
    <tr><th>Logon User</th><td>Anonymous</td></tr> 

   </table> 
   <div class="clear"></div> 
  </div> 
 </fieldset> 
</div> 
<div class="content-container"> 
 <fieldset><legend>Most likely causes:</legend> 
  <ul>  <li></li> </ul> 
 </fieldset> 
</div> 
<div class="content-container"> 
 <fieldset><legend>Things you can try:</legend> 
  <ul>  <li>Create a tracing rule to track failed requests for this HTTP status code. For more information about creating a tracing rule for failed requests, click <a href="http://go.microsoft.com/fwlink/?LinkID=66439">here</a>. </li> </ul> 
 </fieldset> 
</div> 


<div class="content-container"> 
 <fieldset><legend>Links and More Information</legend> 
  The request could not be understood by the server due to malformed syntax. 
  <p><a href="http://go.microsoft.com/fwlink/?LinkID=62293&amp;IIS70Error=400,0,0x00000000,7601">View more information &raquo;</a></p> 
  <p>Microsoft Knowledge Base Articles:</p> 
 <ul><li></li></ul> 

 </fieldset> 
</div> 
</div> 
</body> 
</html> 

我曾满怀希望地尝试设置TrySkipIisCustomErrors = True,但没有运气。有任何想法吗?赞赏。谢谢。

【问题讨论】:

【参考方案1】:

尝试将此添加到您的 web.config。我有一个非常相似的问题,这解决了。

<configuration>
  <system.webServer>
    <httpErrors existingResponse="PassThrough" />
  </system.webServer>
</configuration>

【讨论】:

你摇滚。我的 Web Api 位于单独的“服务”区域。我使用上面的配置在该区域的一个空的“视图”文件夹中添加了一个网络配置文件,并修复了它。谢谢。 太棒了!效果很好,并且 TrySkipIisCustom 在 Asp.NET MVC 4 Web API 中不适合我。 我会 +1 这个答案,但它无法解释它的作用。您可以编辑它以添加解释吗? 我不知道 WebAPI 在幕后做了什么,我只知道它让错误从我自己的代码中通过,并且不会将其包装在其他任何东西中。对不起! 这里似乎有(一些)解释:iis.net/configreference/system.webserver/httperrors【参考方案2】:

通常在这种情况下,在响应对象上设置 TrySkipIisCustomErrors = true 就足够了,但在 Web API 的情况下,它有时无法解决问题(Web API 甚至尝试在内部自行设置此标志)。对于这种情况,您可以考虑更改 IIS 配置。请看一下here(您应该对existingResponse="PassThrough" 最感兴趣)。

【讨论】:

TrySkipIisCustomErrors 似乎不是 WebApi 的 HttpResponseMessage 的成员。【参考方案3】:

假设您在 APIController 内部并且不需要 ExceptionFilterAttribute 来为响应做任何额外的工作,那么只需返回带有错误状态代码的响应,而不是抛出 HttpResponseException。

return Request.CreateResponse(HttpStatusCode.BadRequest, "Invalid model.");

【讨论】:

我注意到的一件事是我必须指定第二个参数(内容),否则 IIS 仍会显示自定义错误页面。【参考方案4】:

我在使用 Asp.Net Webform 应用程序时遇到了同样的问题。客户端向服务器 Web 处理程序 (*.ashx) 发送 ajax 调用。

我想将异常消息返回给用户。 Web 处理程序只发回异常消息和 http 状态代码 400。

诀窍在于 Response.TrySkipIisCustomErrors = true;

try

//do some coding

catch (Exception exception)

    Log.Error(exception);
    context.Server.ClearError();
    context.Response.TrySkipIisCustomErrors = true;
    context.Response.ContentType = "text/plain";
    context.Response.Write(exception.Message);
    context.Response.StatusCode = 400;
    //400 Bad Request
    //The server cannot or will not process the request due to an apparent client error
    //
    //intentionally hidden exception 
    //prevent to send yellow page of death in ajax response

【讨论】:

【参考方案5】:

我遇到了同样的情况,返回:

httpResponseMessage = context.Request.CreateResponse(statusCode);

添加 并没有修复它,响应中缺少 Content-type 和内容正文。

解决它的方法是像这样构造 HttpResponseMessage:

var httpResponseMessage = context.Request.CreateResponse(statusCode, reasonPhrase);

通过包含“value”参数(在本例中为“reasonPhrase”),响应中存在内容类型和内容主体。

【讨论】:

【参考方案6】:

我遇到过从另一个端点调用 WebApi 端点的情况,并且在阅读了 HttpClients 应该是静态的之后,我进行了更改。对于几十条消息工作正常,但随后会被自主机实例拦截,该实例将返回 400 错误请求。似乎没有任何问题,尤其是最初的成功,但是我的原始代码会在调用之前向客户端添加一个默认标头。在我将客户端设置为静态之后,这意味着我要多次将标头添加到同一个客户端。我将代码更改为发送创建并发送 HttpRequestMessage 而不是让客户端执行此操作,并将标头添加到请求中。似乎解决了我的问题。

【讨论】:

以上是关于ASP.NET Web Api HttpResponseException 400 (Bad Request) 被 IIS 劫持的主要内容,如果未能解决你的问题,请参考以下文章

Asp.Net Web API 2第三课——.NET客户端调用Web API

Web API1.1 ASP.NET Web API入门

Asp.Net Web API 2第六课——Web API路由和动作选择

Asp.Net Web API 2第十三课——ASP.NET Web API中的JSON和XML序列化

Asp.Net Web API 2第七课——Web API异常处理

将文件从 ASP.NET Core Web api 发布到另一个 ASP.NET Core Web api