Azure App Service在ApplicationHost.config中设置自定义ConnectionTimeout

时间:2016-04-20 08:56:30

标签: asp.net-mvc azure timeout azure-web-app-service applicationhost

在Azure App Service上托管的ASP.NET MVC网站上,我们要对超过15秒的请求强制超时。这是一个简单的动作,总是花费超过15秒(即无限循环),我们一直在测试......

    public ActionResult TimeoutTest()
    {
        var i = 1;
        while (true)
        {
            i++;
        }
        return new HttpStatusCodeResult(200);
    }

默认情况下,如果我在浏览器中执行该操作的GET,我会得到一个" 500 - 请求超时"两分钟后出现错误,这与the "connectionTimeout" default setting in the webLimits section of ApplicationHost.config同意。

所以...除非我弄错了,否则将此connectionTime值更改为15秒就足够了。为此,我理解需要对ApplicationHost.config文件(XDT)使用基于转换的方法,如here所述。

我使用以下applicationHost.xdt文件...

执行此操作
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<system.applicationHost>
      <webLimits xdt:Transform="SetAttributes(connectionTimeout)" connectionTimeout="00:00:15"/>
</system.applicationHost>
</configuration>

...之后我将文件添加到了正确的位置(d:/home/site/applicationHost.xdt)。我重新启动了我的网站,并在日志中看到变换已成功应用:

2016-04-20T08:40:44 Start 'site' site extension transform
2016-04-20T08:40:44 StartSection Executing SetAttributes (transform line 4, 18)
2016-04-20T08:40:44 on /configuration/system.applicationHost/webLimits
2016-04-20T08:40:44 Applying to 'webLimits' element (no source line info)
2016-04-20T08:40:44 Set 'connectionTimeout' attribute
2016-04-20T08:40:44 Set 1 attributes
2016-04-20T08:40:44 EndSection Done executing SetAttributes
2016-04-20T08:40:44 Successful 'D:\home\site\applicationHost.xdt' site extension transform
2016-04-20T08:40:44 sandboxproc.exe complete successfully. Ellapsed = 316.00 ms

[编辑]:我在转换后直接检查了applicationhost.config,新值是:

    ...
    </sites>
    <webLimits connectionTimeout="00:00:15" />
  </system.applicationHost>
  <system.webServer>
    <asp>
    ...

尽管如此,如果我再次点击上面的动作方法,它仍会在两分钟而不是15秒后超时。

我的问题:有人知道为什么这个超时设置没有得到尊重吗?

我知道this post,它看起来采用完全相同的方法(并且似乎有用吗?)。

1 个答案:

答案 0 :(得分:1)

如何通过Web.Config?

使用executionTimeout
<system.web>
    <httpRuntime executionTimeout="30" />
    <compilation debug="false" />
</system.web>

对于MVC项目,您应该添加以下代码以强制将值应用于请求:

System.Web.HttpContext.Current.GetType().GetField("_timeoutState", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).SetValue(System.Web.HttpContext.Current, 1);

如果您希望每个请求都尊重此设置,您可以创建一个操作过滤器:

public class Timeoutter : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        System.Web.HttpContext.Current.GetType().GetField("_timeoutState", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).SetValue(System.Web.HttpContext.Current, 1);
        base.OnActionExecuting(filterContext);
    }
}

在Global.asax中调用的RegisterGlobalFilters方法中添加注册:

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new Timeoutter());
    filters.Add(new HandleErrorAttribute());
}

请参阅: