是否可以在IIS HttpModule中修改HttpRequest POST的内容?
我需要在IIS中修改某些HttpRequests(SSAS连接字符串)的内容。 基本上,我需要向请求中包含的SOAP添加一个元素。
到目前为止,我的方法是向HttpRequest添加一个Filter,并在filter的Read方法中执行更改。 据我所知,Read永远不会被执行。
我对Request.Filter的理解是它从IIS处理请求时读取,因此IIS应该看到我修改过的Request。
我正在尝试使用HttpModule实际可行,并且我的Filter方法是否正确?
如果是这样,什么会导致Read不被击中?
这是我的代码的简化版本:
public class CustomHttpModule : IHttpModule { private HttpApplication app; public string ModuleName { get { return "CustomHttpModule"; } } public void Init(HttpApplication context) { app = context; context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute); } void context_PreRequestHandlerExecute(object sender, EventArgs e) { var request = app.Context.Request; request.Filter = new CustomHttpFilter(request.Filter); } } public class CustomHttpFilter : Stream { private Stream outputStream; public CustomHttpFilter(Stream outputFilter) { outputStream = outputFilter; } public override int Read(byte[] buffer, int offset, int count) { // read and make the necessary changes } }
我不相信可以使用http模块修改请求 ,但是可以修改响应 。 HttpRequest
对象大部分是只读的,因此它通常在任何上下文中都是不可变的,而不仅仅是来自模块。
如果你真的很绝望,你可以尝试使用reflection来访问更多的http请求对象。 但是,要访问,修改或调用非公共成员,您的进程将需要完全信任权限, 这在Web环境中非常危险 。
实际上,可以通过 IIS 7.0+中的HttpModule修改IIS中HttpRequest POST的内容 。 我有这个问题,并且能够解决它。 我发布以供将来参考,因为没有很多post详细说明何时/为什么它将起作用或不起作用。
这是一个故障排除清单:
-
确保您的模块和任何其他模块没有访问Request对象,以便在将filter添加到请求filter之前评估输入流。 例如,访问
Request.Form["param"]
将触发输入流的评估。 这种情况的一个症状是从未调用filterRead
方法。 -
查看统一IIS管道中的事件顺序https://msdn.microsoft.com/en-us/library/bb470252.aspx 。 您将看到
PreRequestHandlerExecute
事件与第12个事件一样发生。 为了最好地设置请求filter并将其应用,您应该在BeginRequest
事件中执行此操作,这是请求validation和url映射之后的第一个事件(在HttpModule中公开,在ISAPI扩展或filter中有其他公开) 。 ISAPIfilter和扩展确实有一些事件可能发生在HttpModule事件之前,但从那以后 -
考虑到Request.Filter是Streams链,它们会连续评估,将输出从一个传递到下一个输入,它们也可以在模块接收输入之前修改请求。 如果存在一些奇怪的行为,请考虑删除其他一些filter以隔离问题或更改它们的加载顺序。
-
还要考虑Streamfilter的读取和写入方法是以块的forms调用的,因此它们可以被多次调用,具有不同的偏移量,因此请确保您的重写逻辑正常运行,特别是如果您要替换导致不同总体请求或响应大小的内容见下文。
-
如果要在“读取”或“写入”中执行搜索/替换,则需要考虑数据可能跨越多个读/写。 在这种情况下,您可能需要考虑在MemoryStream中缓冲请求或响应流并对其进行操作。
如果您将问题隔离并简化为最基本的方案,您最终将确定导致其无法工作的原因。 这里的简单示例演示了https://msdn.microsoft.com/en-us/library/system.web.httprequest.filter.aspx,但它没有演示在缓冲流上运行。
我已经整理了一个示例,演示了缓冲请求和响应重写HttpModule以供参考。 https://github.com/snives/HttpModuleRewrite
通过覆盖WorkerRequest可以实现。 您可以获得如下的当前工作人员请求:
(HttpWorkerRequest)context.GetService(typeof(HttpWorkerRequest))
您可以通过引用IIS7WorkerRequest.cs .net参考源来实现派生的工作者请求。
硬部分从输入流中读取所有字节并解析数据。 您应该知道HTTP Multipart-form数据规范。
- 是否有可能杀死WaitForSingleObject(句柄,INFINITE)?
- 尝试设置TextBox.IsReadOnly时出现奇怪的XAML解析错误
- 可视树外的数据绑定。 数据上下文桥接
- 聚合函数Sum()和Type:String的使用无效
- 如何在我的c#应用程序中执行* .sql mysql文件
- 当我使用List 时,我在Jetbrains dotMemory中看到的这个“pinning handle object ”是什么?
- 如何在C#中使用WS-Security?
- Easy XPathNavigator GetAttribute
- 使用Environment.Is64BitProcess从c#应用程序动态调用32位或64位DLL