2
votes

I need to test an helper class which manage complex querystring.

I use this helper method to mock the HttpContext:

public static HttpContext FakeHttpContext(string url, string queryString)
{
    var httpRequest = new HttpRequest("", url, queryString);
    var stringWriter = new StringWriter();
    var httpResponse = new HttpResponse(stringWriter);
    var httpContext = new HttpContext(httpRequest, httpResponse);

    var sessionContainer = new HttpSessionStateContainer("id", new SessionStateItemCollection(),
                                            new HttpStaticObjectsCollection(), 10, true,
                                            HttpCookieMode.AutoDetect,
                                            SessionStateMode.InProc, false);
    SessionStateUtility.AddHttpSessionStateToContext(httpContext, sessionContainer);

    return httpContext;
}

The problem is that the HttpRequest loses the querystring:

HttpContext.Current = MockHelpers.FakeHttpContext("http://www.google.com/", "name=gdfgd");

HttpContext.Current.Request.Url is "http://www.google.com/" and not "http://www.google.com/?name=gdfgd"as expected.

If I debug I see that just after the HttpRequest constrctor the querystring is lost.

The workaround I'm using is to pass the url with querystring to the HttpRequest constructor:

HttpContext.Current = MockHelpers.FakeHttpContext("http://www.google.com/?name=gdfgd","");
2
I don't know enough about this, but I did copy your code and run it. You are right about the querystring not showing up in the url, but it is not completely gone from the HttpContext as the QueryString property still has it. I don't know what is expected behavior though.Halvard
@Halvard thanks, your comment has pointed me to the solution!giammin

2 Answers

2
votes

Thanks to Halvard's comment I had the clue to find the answer:

HttpRequest constructor parameters are disconnected between them.

The url parameter is used to create the HttpRequest.Url and the queryString is used for HttpRequest.QueryString property: they are detached

To have a consistent HttpRequest with an url with querystring you have to:

var httpRequest = new HttpRequest
      ("", "http://www.google.com/?name=gdfgd", "name=gdfgd");

Otherwise you'll have either the Url or the QueryString property not correctly loaded.

There is my updated Mock Helpers method:

public static HttpContext FakeHttpContext(string url)
{
    var uri = new Uri(url);
    var httpRequest = new HttpRequest(string.Empty, uri.ToString(), uri.Query.TrimStart('?'));
    var stringWriter = new StringWriter();
    var httpResponse = new HttpResponse(stringWriter);
    var httpContext = new HttpContext(httpRequest, httpResponse);

    var sessionContainer = new HttpSessionStateContainer("id", new SessionStateItemCollection(),
                                            new HttpStaticObjectsCollection(), 10, true,
                                            HttpCookieMode.AutoDetect,
                                            SessionStateMode.InProc, false);
    SessionStateUtility.AddHttpSessionStateToContext(httpContext, sessionContainer);

    return httpContext;
}
0
votes

Try this:

Uri uriFull = new Uri(HttpContext.Current.Request.Url, HttpContext.Current.Request.RawUrl);