2

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","");
giammin
  • 17,130
  • 6
  • 64
  • 84
  • 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 Oct 31 '13 at 12:40
  • @Halvard thanks, your comment has pointed me to the solution! – giammin Oct 31 '13 at 13:59

2 Answers2

2

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;
}
Community
  • 1
  • 1
giammin
  • 17,130
  • 6
  • 64
  • 84
0

Try this:

Uri uriFull = new Uri(HttpContext.Current.Request.Url, HttpContext.Current.Request.RawUrl);
Jim Rhodes
  • 4,374
  • 2
  • 21
  • 34