asp.net – 两次调用HttpModule EndRequest处理程序

前端之家收集整理的这篇文章主要介绍了asp.net – 两次调用HttpModule EndRequest处理程序前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试为在WCF中实现并托管在Azure上的REST服务实现身份验证.我正在使用HttpModule来处理AuthenticationRequest,PostAuthenticationRequest和EndRequest事件.如果Authorization标头丢失或其中包含的标记无效,则在EndRequest期间我将响应的StatusCode设置为401.但是,我已确定EndRequest被调用两次,而在第二次调用时响应已经有标题set,导致设置StatusCode的代码抛出异常.

我向Init()添加了锁,以确保处理程序没有被注册两次;还是跑了两次. Init()也运行了两次,表明正在创建两个HttpModule实例.但是,在VS调试器中使用Set Object ID似乎表明请求实际上是不同的请求.我在Fiddler中验证过,浏览器只向我的服务发出了一个请求.

如果我切换到使用global.asax路由而不是依赖于WCF服务主机配置,处理程序只调用一次,一切正常.

如果我将配置添加到system.web配置部分以及Web.config中的system.webServer配置部分,则只调用一次处理程序,一切正常.

所以我有缓解,但我真的不喜欢我不理解的行为.为什么处理程序被调用两次?

这是问题的最小重复:

Web.config文件

  1. <system.web>
  2. <compilation debug="true" targetFramework="4.0" />
  3. <!--<httpModules>
  4. <add name="AuthModule" type="TestWCFRole.AuthModule,TestWCFRole"/>
  5. </httpModules>-->
  6. </system.web>
  7. <system.serviceModel>
  8. <behaviors>
  9. <endpointBehaviors>
  10. <behavior name="WebBehavior">
  11. <webHttp/>
  12. </behavior>
  13. </endpointBehaviors>
  14. <serviceBehaviors>
  15. <behavior>
  16. <!-- To avoid disclosing Metadata information,set the value below to false and remove the Metadata endpoint above before deployment -->
  17. <serviceMetadata httpGetEnabled="true" />
  18. <!-- To receive exception details in faults for debugging purposes,set the value below to true. Set to false before deployment to avoid disclosing exception information -->
  19. <serviceDebug includeExceptionDetailInFaults="true"/>
  20. </behavior>
  21. </serviceBehaviors>
  22. </behaviors>
  23. <serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true" />
  24. <services>
  25. <service name="TestWCFRole.Service1">
  26. <endpoint binding="webHttpBinding" name="RestEndpoint" contract="TestWCFRole.IService1" bindingConfiguration="HttpSecurityBinding" behaviorConfiguration="WebBehavior"/>
  27. <host>
  28. <baseAddresses>
  29. <add baseAddress="http://localhost/" />
  30. </baseAddresses>
  31. </host>
  32. </service>
  33. </services>
  34. <standardEndpoints>
  35. <webHttpEndpoint>
  36. <standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true"/>
  37. </webHttpEndpoint>
  38. </standardEndpoints>
  39. <bindings>
  40. <webHttpBinding>
  41. <binding name="HttpSecurityBinding" >
  42. <security mode="None" />
  43. </binding>
  44. </webHttpBinding>
  45. </bindings>
  46. </system.serviceModel>
  47. <system.webServer>
  48. <modules runAllManagedModulesForAllRequests="true">
  49. <add name="AuthModule" type="TestWCFRole.AuthModule,TestWCFRole"/>
  50. </modules>
  51. <directoryBrowse enabled="true"/>
  52. </system.webServer>

Http模块:

  1. using System;
  2. using System.Web;
  3.  
  4. namespace TestWCFRole
  5. {
  6. public class AuthModule : IHttpModule
  7. {
  8. /// <summary>
  9. /// You will need to configure this module in the web.config file of your
  10. /// web and register it with IIS before being able to use it. For more information
  11. /// see the following link: http://go.microsoft.com/?linkid=8101007
  12. /// </summary>
  13. #region IHttpModule Members
  14.  
  15. public void Dispose()
  16. {
  17. //clean-up code here.
  18. }
  19.  
  20. public void Init(HttpApplication context)
  21. {
  22. // Below is an example of how you can handle LogRequest event and provide
  23. // custom logging implementation for it
  24. context.EndRequest += new EventHandler(OnEndRequest);
  25. }
  26.  
  27. #endregion
  28.  
  29. public void OnEndRequest(Object source,EventArgs e)
  30. {
  31. HttpContext.Current.Response.StatusCode = 401;
  32. }
  33. }
  34. }

解决方法

对不起,为什么它可以被调用两次没有任何线索,但是EndRequest最终可能因多种原因被调用.请求完成,请求被中止,发生了一些错误.因此,我不相信假设如果你到达那里,你实际上有401,这可能是出于其他原因.

我只是将我的逻辑保留在AuthenticateRequest管道中:

  1. public class AuthenticationModule : IHttpModule
  2. {
  3. public void Dispose() { }
  4.  
  5. public void Init(HttpApplication context)
  6. {
  7. context.AuthenticateRequest += Authenticate;
  8. }
  9.  
  10. public static void Authenticate(object sender,EventArgs e)
  11. {
  12. // authentication logic here
  13. //.............
  14.  
  15. if (authenticated) {
  16. HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(myUser,myRoles);
  17. }
  18.  
  19. // failure logic here
  20. //.............
  21. }
  22. }

猜你在找的asp.Net相关文章