如何在“模拟”BaseHttpContext上设置IP(UserHostAddress)?

时间:2012-10-31 11:41:27

标签: c# asp.net .net mocking

我正在尝试创建一个虚拟BaseHttpContext来进行一些(模拟)测试而无需执行实际请求。我想在我的虚拟上下文中添加一个IP地址。

string url = "http://www.google.com";

//wrap in uri
Uri uri = new Uri(url);

//create request
var request = new HttpRequest("", uri.GetLeftPart(UriPartial.Path), uri.Query);
request.ServerVariables.Add("REMOTE_ADDR", ip);

//dummy context
HttpContext context = new HttpContext(
    new HttpRequest("", uri.GetLeftPart(UriPartial.Path), uri.Query),
    new HttpResponse(new StringWriter(System.Text.Encoding.UTF8))
);

//wrap context
var contextWrapper = new HttpContextWrapper(context);

知识产权应反映在BaseHttpContext.Request.UserHostAddress中。像这样添加IP:request.ServerVariables.Add("REMOTE_ADDR", ip);会导致以下异常:

  

不支持指定的方法。

2 个答案:

答案 0 :(得分:1)

看起来伪造HttpContext并不容易,需要做很多工作。使用模拟框架可以使事情变得更容易。以下是使用Moq的示例:

/// <summary>
/// Fakes the HTTP context.
/// </summary>
/// <param name="url">The URL.</param>
/// <param name="ip">The ip.</param>
/// <param name="referrer">The referrer.</param>
/// <returns>A HTTP context.</returns>
public static HttpContextBase FakeHttpContext(string url, string ip, string referrer)
{
    Uri uri = new Uri(url);

    var context = new Mock<HttpContextBase>();
    var files = new Mock<HttpFileCollectionBase>();
    var request = new Mock<HttpRequestBase>();
    var response = new Mock<HttpResponseBase>();
    var session = new Mock<HttpSessionStateBase>();
    var server = new Mock<HttpServerUtilityBase>();
    var user = new Mock<IPrincipal>();
    var identity = new Mock<IIdentity>();

    request.Setup(req => req.ApplicationPath).Returns("~/");
    request.Setup(req => req.AppRelativeCurrentExecutionFilePath).Returns("~/");
    request.Setup(req => req.PathInfo).Returns(string.Empty);
    request.Setup(req => req.Form).Returns(new NameValueCollection());
    request.Setup(req => req.QueryString).Returns(HttpUtility.ParseQueryString(uri.Query));
    request.Setup(req => req.Files).Returns(files.Object);
    request.Setup(req => req.UserHostAddress).Returns(ip);
    request.Setup(req => req.UrlReferrer).Returns(new Uri(referrer));
    request.Setup(req => req.Url).Returns(uri);
    request.Setup(req => req.RawUrl).Returns(url);

    response.Setup(res => res.ApplyAppPathModifier(It.IsAny<string>())).Returns((string virtualPath) => virtualPath);

    user.Setup(usr => usr.Identity).Returns(identity.Object);

    identity.SetupGet(ident => ident.IsAuthenticated).Returns(true);

    context.Setup(ctx => ctx.Request).Returns(request.Object);
    context.Setup(ctx => ctx.Response).Returns(response.Object);
    context.Setup(ctx => ctx.Session).Returns(session.Object);
    context.Setup(ctx => ctx.Server).Returns(server.Object);
    context.Setup(ctx => ctx.User).Returns(user.Object);

    return context.Object;
}

this git post的启发。

答案 1 :(得分:1)

This post非常有帮助。要解决您的问题,您只需要在帖子中实施HttpRequestExtensionsNameValueCollectionExtensions类。

你可以像这样使用它:

string url = "http://127.0.0.1";
var request = new HttpRequest(string.Empty, url, string.Empty);
request.AddServerVariable("REMOTE_ADDR", "127.0.0.1");