我一直在使用Hanselman博客上发现的MvcMockHelpers类来传递一个模拟的 HttpContext.我们对它进行了一些扩展,以添加我们需要的一些身份验证数据,而且大多数情况下这都很棒.
我们遇到的问题是我们给控制器的上下文在HttpContext.Response.Output中有一个空值,这会导致抛出一些异常.我不确定要添加什么才能使其正常工作.
这是现有的FakeHttpConext()方法:
public static HttpContextBase FakeHttpContext()
{
var context = new Mock<HttpContextBase>();
var request = new Mock<HttpRequestBase>();
var response = new Mock<HttpResponseBase>();
var session = new Mock<HttpSessionStateBase>();
var server = new Mock<HttpServerUtilityBase>();
// Our identity additions ...
var user = new Mock<IPrincipal>();
OurIdentity identity = (OurIdentity)Thread.CurrentPrincipal.Identity;
context.Expect(ctx => ctx.Request).Returns(request.Object);
context.Expect(ctx => ctx.Response).Returns(response.Object);
context.Expect(ctx => ctx.Session).Returns(session.Object);
context.Expect(ctx => ctx.Server).Returns(server.Object);
context.Expect(ctx => ctx.User).Returns(user.Object);
context.Expect(ctx => ctx.User.Identity).Returns(identity);
return context.Object;
}
Run Code Online (Sandbox Code Playgroud)
这是爆炸方法(它是MVC Contrib项目的XmlResult的一部分):
public override void ExecuteResult(ControllerContext context)
{ …Run Code Online (Sandbox Code Playgroud) 我总是在ASP.NET中以某种方式伪装/模拟/存根HttpContext(在ASP.NET MVC/MonoRail中更容易).
但是我可以看到HttpContext本身可以很容易地构造,字面上只有几行代码.
var tw = new StringWriter();
var workerReq = new SimpleWorkerRequest("/webapp", @"c:\here\there\wwwroot", "page.aspx", tw);
var context = new HtpContext(workerReq);
Run Code Online (Sandbox Code Playgroud)
如果我们将这个代码包装成这样的东西它应该工作正常,我们甚至可以使用它来渲染ASPX:
using(Simulate.HttpContext()) {
HttpContext.Current.BlaBla;
}
Run Code Online (Sandbox Code Playgroud)
所以问题是:
我记得Phill Haack使用Reflection hacks构建HttpContext的帖子.
但它似乎并不需要.
干杯,
德米特里.
我有一个我无法解决的场景:
我正在为mvc创建自己的自定义授权属性.我想添加的主要功能是能够更改用户重定向的位置(如果用户不在某个角色中).我不介意系统发送他们回到登录页面,如果他们没有通过身份验证,但我想选择在那里给他们,如果他们进行身份验证,但不允许访问该操作方法.
这是我想做的事情:
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
public string Action;
public string Controller;
protected override bool AuthorizeCore(System.Web.HttpContextBase httpContext)
{
// if User is authenticated but not in the correct role
string url = Url.Action(this.Action, this.Controller);
httpContext.Response.Redirect(url);
}
}
Run Code Online (Sandbox Code Playgroud)
作为一个额外的奖励,我想在进行重定向之前访问ViewContext和TempData.
有关如何在属性中实例化UrlHelper和ViewContext的任何想法?
asp.net asp.net-mvc asp.net-membership custom-attributes httpcontext
我正在使用HttpContext.Current.Items来创建一个Per-Request Cache Store.我遇到了奇怪的问题,因为我在不同的http请求上遇到很多缓存条目.
似乎HttpContext.Current.Items在多个http请求中重用.这是正常的吗?
我在WCF中编写了一个简单的REST API,并且身份验证机制使用API密钥.一旦客户端在请求头中提交API密钥,我在服务器端(在覆盖RequestInterceptor类的ProcessRequest()方法的BaseService类中)检查它,如下所示:
public partial class BaseService : RequestInterceptor
{
public BaseService() : base(false) { }
#region Process Request
public override void ProcessRequest(ref RequestContext requestContext)
{
if (IsValidApiKey(requestContext))
//put some values in HttpContext object.
}
Run Code Online (Sandbox Code Playgroud)
...
现在我在我的REST服务中启用了aspnet兼容性,但我仍然无法在上面的ProcessRequest覆盖中访问HttpContext对象. 请注意,可以从服务方法内部访问HttpContext,但不能在ProcessRequest方法中访问.
有什么想法吗?
我的一个服务使用IIS通过此类代码提供的服务器变量
var value = System.Web.HttpContext.Current.Request.ServerVariables["MY_CUSTOM_VAR"];
Run Code Online (Sandbox Code Playgroud)
我试过的是模拟那些对象并插入我自己的变量/集合并检查几个案例(例如变量丢失,值为null ...)我能够创建HttpContext,HttpRequest,HttpResponse的实例并分配它们但是它们中的每一个都只是一个没有接口或虚拟属性的普通类,并且ServerVariables的初始化发生在某个地方.
HttpContext嘲笑:
var httpRequest = new HttpRequest("", "http://excaple.com/", "");
var stringWriter = new StringWriter();
var httpResponse = new HttpResponse(stringWriter);
var httpContextMock = new HttpContext(httpRequest, httpResponse);
HttpContext.Current = httpContextMock;
Run Code Online (Sandbox Code Playgroud)
尝试#1通过反射调用私有方法
var serverVariables = HttpContext.Current.Request.ServerVariables;
var serverVariablesType = serverVariables.GetType();
MethodInfo addStaticMethod = serverVariablesType.GetMethod("AddStatic", BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.NonPublic);
addStaticMethod.Invoke(serverVariables, new object[] {"MY_CUSTOM_VAR", "value"});
Run Code Online (Sandbox Code Playgroud)
失败,错误表明集合是只读的.
尝试#2用我自己的实例替换ServerVariables
var request = HttpContext.Current.Request;
var requestType = request.GetType();
var variables = requestType.GetField("_serverVariables", BindingFlags.Instance | BindingFlags.NonPublic);
variables.SetValue(request, new NameValueCollection
{ …Run Code Online (Sandbox Code Playgroud) 我有一个FakeHttpContext我一直在尝试修改以包含一些标题用于测试目的
public static HttpContext FakeHttpContext()
{
var httpRequest = new HttpRequest("", "http://stackoverflow/", "");
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 });
return httpContext;
}
Run Code Online (Sandbox Code Playgroud)
此作品,未经头,但是当我添加任何的代码行中之间的HttpRequest和StringWriter的线.
httpRequest.Headers.Add("blah", "1234");
httpRequest.Headers["blah"] = "1234";
Run Code Online (Sandbox Code Playgroud)
它抛出
System.Web.dll中发生了'System.PlatformNotSupportedException'类型的异常,但未在用户代码中处理
我编写用于使用令牌进行身份验证的中间件。(不要问我:“为什么?”)。
...
private UserManager<ApplicationUser> userManager;
private RequestDelegate next;
private WareHouseDbContext context;
...
public async Task Invoke(HttpContext httpContext)
{
var header = httpContext.Request.Headers.Where(x => x.Key == "Authorization");
if (header.Count() == 1)
{
var token = header.First().Value.First();
if (token.Contains("Bearer"))
{
var name = TokenEncryptor.Decrypt(token.Replace("Bearer ", ""));
var user = context.Users.FirstOrDefault(x => x.UserName == name);
if (user != null)
{
httpContext.User = user; // ???? how do this ???/
}
}
}
await next.Invoke(httpContext);
}
Run Code Online (Sandbox Code Playgroud)
请回答我如何设置httpContext.User?
我创建了一个其他网站可以用来在我的数据库中存储错误的Web服务.然后,他们可以访问我的网站查看他们的错误,搜索错误,过滤错误等.但是,我的Web服务出现以下错误:
System.Web.HttpContext无法序列化,因为它没有无参数构造函数.
描述:执行当前Web请求期间发生未处理的异常.请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息.
异常详细信息:System.InvalidOperationException:System.Web.HttpContext无法序列化,因为它没有无参数构造函数.
Web服务包含以下功能:
[WebMethod]
public static void LogError(HttpContext context, Exception exception, string APIKey)
{
//Log the error
}
使用Web服务记录异常的外部站点在global.asax文件中包含以下代码:
void Application_Error(object sender, EventArgs e)
{
// Code that runs when an unhandled error occurs
WebService.Errors.ErrorHandler.LogError(HttpContext.Current, Server.GetLastError(), "NOLDFHOI");
}
如何从Web站点将HttpContext从其站点获取到我的函数中?
由于我在使用Moq框架(ASP.NET MVC -使用Moq框架测试RenderPartialViewToString()的单元测试RenderPartialViewToString())时遇到问题,我正在考虑直接获取控制器,而不使用Moq进行这些特定测试,但是,如何在不使用任何Moq框架的情况下为我的测试模拟(或设置)HttpContext?
我需要能够做类似的事情,当然没有Moq:
var mockHttpContext = new Mock<ControllerContext>();
mockHttpContext.SetupGet(p => p.HttpContext.User.Identity.Name).Returns("n1\\test");
mockHttpContext.SetupGet(p => p.HttpContext.Request.IsAuthenticated).Returns(true);
Run Code Online (Sandbox Code Playgroud)
非常感谢你.
httpcontext ×10
asp.net ×6
asp.net-mvc ×4
c# ×4
unit-testing ×3
mocking ×2
caching ×1
identity ×1
items ×1
moq ×1
reflection ×1
rest ×1
testing ×1
wcf ×1
web-services ×1