如何在请求中设置用户主机地址



我发现这段代码是为了进行单元测试而进行模拟请求。我正在尝试设置用户主机地址,但我不清楚如何使用此代码中概述的相同方法来实现这一目标。我认为这必须通过反射来完成,因为我发现不允许设置标题。有什么想法吗?

public static HttpContext FakeHttpContext()
        {
            var httpRequest = new HttpRequest("", "http://fakurl/", "");
            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);
            httpContext.Items["AspSession"] = typeof(HttpSessionState).GetConstructor(
                                        BindingFlags.NonPublic | BindingFlags.Instance,
                                        null, CallingConventions.Standard,
                                        new[] { typeof(HttpSessionStateContainer) },
                                        null)
                                .Invoke(new object[] { sessionContainer });
            httpContext.Request.Headers["REMOTE_ADDR"] = "XXX.XXX.XXX.XXX"; // not allowed
            return httpContext;
        }

我也尝试了这个模拟库:

https://gist.github.com/rally25rs/1578697

按用户主机地址仍然是只读的。

我发现的最佳方法是拥有某种实现IContextService接口的ContextService。 此类/接口对可以执行您需要的任何操作。关键是,如果您在单元测试(如 MOQ)中使用模拟框架,那么您可以连接模拟上下文服务以返回特定的 IP 地址。

这篇 StackOverflow 帖子有一些很好的指针:Moq:单元测试依赖于 HttpContext 的方法。

更新:

你找到的StackOverflow帖子也是一个很好的帖子:如何在"模拟"的BaseHttpContext上设置IP(UserHostAddress)?

发现通常我只需要上下文/请求/响应对象中的几个属性,所以我经常滚动我自己的较小变体:

public class ContextService : IContextService
{
    public string GetUserHostAddress()
    {
        return HttpContext.Current.Request.UserHostAddress;
    }
}
public interface IContextService
{
    string GetUserHostAddress();
}

使用该类/接口组合,我可以使用 Moq 来连接虚假服务:

var contextMock = new Moq.Mock<IContextService>();
contextMock.Setup(c => c.GetUserHostAddress()).Returns("127.0.0.1");

现在每次打电话contextMock.GetUserHostAddress(),都会得到"127.0.0.1"。 自己滚动可能是一个很好的学习体验,特别是如果你不需要一个成熟的(或尽可能完整的)HttpContext模拟的所有花里胡哨的东西。

最新更新