Search code examples
asp.nethttp-redirecthttpmodule

Check if a redirect then change the query string


I would like to remove the query parameter 'mobile' from all requests that are redirects. The page Redirect.aspx redirects a visitor to Default.aspx?mobile=1. And when a visitor browses to Redirect,aspx, then eventually he should be led to the Default.aspx without a parameter in the address bar. Steps I took: So, I have to remove the query parameter "mobile" from a query string if the current request is a redirect. And here is the problem: I'm checking if status code is 3xx and query has 'mobile' parameter, but this condition never equals true.

Redirect.aspx:

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);
    Context.Response.Redirect("Default.aspx?mobile=1");
}

RemoveParamModule:

public class RemoveParamModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.EndRequest += RewriteHandler;
    }

    private void RewriteHandler(object sender, EventArgs eventArgs)
    {
        var context = (HttpApplication)sender;
        var statusCode = context.Response.StatusCode;
        if (statusCode.IsInRange(300, 399) && context.Request.QueryString["mobile"] != null)
        {
            DeleteMobileParameter(context.Request.QueryString);
            context.Response.Redirect(context.Request.Path, true);
        }
    }

    private static void DeleteMobileParameter(NameValueCollection collection)
    {
        var readOnlyProperty = collection.GetType().GetProperty("IsReadOnly", BindingFlags.Instance | BindingFlags.NonPublic);
        readOnlyProperty.SetValue(collection, false, null);
        collection.Remove("mobile");
        readOnlyProperty.SetValue(collection, true, null);
    }

    public void Dispose()
    {
    }
}

Why do the requests in the module either have statusCode=302 or the parameter 'mobile' but never both at the same time? And how can I remove the parameter 'mobile' for the redirects?


Solution

  • Response.Redirect creates response from server for previously requested URL. Then, client browser receives this response and just GETs new URL, which server will process with usual 200 result.

    So basically:

    Request:  GET Response.aspx
    Response: 302 Default.aspx?mobile=1
    
    Request:  GET Default.aspx?mobile=1
    Response: 200 <body>
    

    So if I correctly understood your needs - you shouldn't parse mobile from Request URL, but analyze you Response instead.

    Also Response.Redirect might throw ThreadAbortException so be careful with several Redirects in the same pipeline.