了解HttpModules和URL操作

时间:2014-07-29 12:19:25

标签: c# query-string httpmodule request.querystring

我正在开发的项目与php应用程序(Revive AdServer FWIW)集成。我们控制它部署的服务器,但改变我认为不可能的代码。 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而不仅仅是操纵上下文。 Request.Query字符串属性(似乎不是同一个)。我想知道我是否需要实现一个UrlRewriter(我不熟悉)。在一个例子中,我看到,context.RewritePath()被调用,但如果在HttpModule中使用,那似乎会导致无限循环/堆栈溢出。

提前感谢您的帮助。

1 个答案:

答案 0 :(得分: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()电话的位置。像魅力一样工作!