理解HttpModules和URL操作

4
我正在处理的项目需要与一个PHP应用程序(Revive AdServer)集成。我们控制它所部署的服务器,但我认为改变代码是不可能的。Revive有调用JavaScript代码,可以在您想要展示广告的站点上部署,并且当该代码渲染在这些站点上时,它会调用PHP应用程序并根据传递的查询字符串智能显示广告。
我们需要做的是在从这些站点发出调用请求后,并在它到达PHP应用程序之前拦截它并操纵查询字符串。为了实现这一点,我编写了一个HttpModule,并将其添加到了PHP应用程序的IIS上。以下是代码:
public class AdServerModule : IHttpModule
{
    public void OnBeginRequest(object sender, EventArgs e)
    {
        var context = ((HttpApplication)sender).Context;
        var queryString = context.Request.QueryString;
        var readonlyProperty = queryString.GetType().GetProperty("IsReadOnly", BindingFlags.Instance | BindingFlags.NonPublic);
        readonlyProperty.SetValue(queryString, false, null);
        queryString.Add("foo", "bar");
        readonlyProperty.SetValue(queryString, true, null);
    }

    public void Init(HttpApplication context)
    {
        context.BeginRequest += new EventHandler(OnBeginRequest);
    }
}

在这个例子中,你可以看到我正在使用反射将&foo=bar添加到请求的查询字符串中。我不确定我是否理解了应该发生什么,但我期望在请求的某个地方看到它,但我没有看到。
此外,我并没有尝试去查找php代码的很多细节,但我相信它正在检查请求的URL以获取查询字符串值,因此似乎我需要更改URL而不仅仅是操纵context.Request.Query string属性(它们似乎不是同一个东西)。我想知道是否需要实现UrlRewriter(我不熟悉如何实现)。在我看到的一个例子中,调用了context.RewritePath(),但如果在HttpModule中使用它,那似乎会导致无限循环/堆栈溢出。
感谢您提前的任何帮助。
1个回答

3

我最终找到了解决方法。原来需要使用RewritePath()方法,我一开始没有正确使用它。现在这是我的代码:

public class AdServerModule : IHttpModule
{
    public void OnBeginRequest(object sender, EventArgs e)
    {
        var context = ((HttpApplication)sender).Context;
        var queryString = context.Request.QueryString;
        var readonlyProperty = queryString.GetType().GetProperty("IsReadOnly", BindingFlags.Instance | BindingFlags.NonPublic);
        readonlyProperty.SetValue(queryString, false, null);
        queryString.Add("foo", "bar");

        var path = GetVirtualPath(context);
        context.RewritePath(path, String.Empty, queryString.ToString());

        readonlyProperty.SetValue(queryString, true, null);
    }

    public void Init(HttpApplication context)
    {
        context.BeginRequest += new EventHandler(OnBeginRequest);
    }

    private static string GetVirtualPath(HttpContext context)
    {
        string path = context.Request.RawUrl;
        var queryStringLength = path.IndexOf("?");
        path = path.Substring(0, queryStringLength >= 0 ? queryStringLength : path.Length);
        path = path.Substring(path.LastIndexOf("/") + 1);
        return path;
    }
}

您可以看到我添加了context.RewritePath()调用。这个方法非常好用!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接