我有很多依赖于HttpContext.Current的代码,我注意到来自SignalR集线器的请求有HttpContext.Current == null,所以我的代码断了,例如:
HttpContext.Current.Request.IsAuthenticated
Run Code Online (Sandbox Code Playgroud)
所以我想出了以下内容:
public static class UnifiedHttpContext
{
private static HubCallerContext SignalRContext { get; set; }
private static int SignalRUserId
{
get { return WebSecurity.GetUserId(SignalRContext.User.Identity.Name); }
}
private static bool IsSignalRRequest
{
get { return SignalRContext != null; }
}
public static void SetSignalRContext(HubCallerContext context)
{
SignalRContext = context;
}
public static bool IsAuthenticated
{
get
{
if (!IsSignalRRequest)
{
return System.Web.HttpContext.Current.Request.IsAuthenticated;
}
else
{
return SignalRContext.User.Identity.IsAuthenticated;
}
}
}
public static int UserId
{
get …Run Code Online (Sandbox Code Playgroud) 用户点击页面spawn.aspx,然后生成六个线程,渲染页面全部使用
((System.Web.IHttpHandler)instance).ProcessRequest(reference to spawn's HTTPContext);
Run Code Online (Sandbox Code Playgroud)
不要担心ASP.Net似乎正在向用户发送1个请求的响应,该部分被处理并且只发送一个响应.
问题是,在具有许多线程(quad-quads)的高流量环境(我们的生产环境)中,我们得到一个错误:
Run Code Online (Sandbox Code Playgroud)System.IndexOutOfRangeException at System.collections.ArrayList.Add at System.Web.ResponseDependencyList.AddDependencies(String[] items, String argname, Boolean cloneArray, DateTime utcDepTime) at System.Web.ResponseDependencyList.AddDependencies(String[] items, String argname, Boolean cloneArray, String requestVritualPath) at System.Web.UI.Page.AddWrappedFileDependencies(Object virtualFileDependencies) at ASP.spawned_page_no_1_aspx.FrameworkInitialize() at System.Web.UI.Page.ProcessRequest
我们不能在别处复制它.我的同事认为这是因为我正在重用原始的HTTPContext并将其传递给其他线程,并且它不是线程安全的.
遵循这个逻辑,我尝试将新的HTTPContext传递给线程.但它的一部分似乎不会"结合".具体来说,我需要将Session对象放入新的HTTPContext中.我想我也想要其他部分,比如Cache.对于记录,HTTPContext.Current.Session.IsSynchronized为false.
我的问题是:
编辑:更多详细信息
所以回到这句话:"不要担心ASP.Net似乎正在向用户发送1个请求的响应,该部分被处理,只有一个响应被发送." Raymond Chen的巨大粉丝,我同意你的观点:"现在你有两个问题"是一个合理的陈述,如果没有更多的信息.
实际发生的是我正在构建一个Excel文档来发回.在spawn.aspx页面中,它设置了一些状态信息,包括它渲染为excel的事实,以及进行渲染的对象.每个衍生的页面都会获取该信息,并将阻止它们轮到渲染到该对象.如果字面上看起来像这样:
protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
if (this.RenderToExcel)
{
Deadlocker.SpinUntilCurrent(DeadLockToken);
RenderReport(this, this.XLSWriter);
Deadlocker.Remove(DeadLockToken);
}
else
base.Render(writer);
}
Run Code Online (Sandbox Code Playgroud)
但到目前为止的所有处理 - 数据库访问,控制层次,所有这些都是并行完成的.并且它有很多 - 足够的,它仍然让它阻止渲染它的一部分将把总时间减少一半以上.
最好的部分是 - 没有必要为Excel渲染重写.所有控件都知道如何将自己渲染为excel,并且您可以独立访问每个衍生页面(实际上是'正常情况' - excel报告只是所有衍生页面的聚合.)
所以我认为最终的结果将是"你不能这样做,你需要重新思考这种方法" - 但我必须至少尝试一下,因为事实上一切都运行良好而不重复任何逻辑或任何代码或不得不抽象任何东西是如此完美.而且只有多线程就是问题,如果我按顺序渲染页面,一切都很好,只是很慢.
HttpContext.Current.Items[...]vs存储数据ViewData[...]?我试图弄清楚在这个集合中存储数据的最佳实践,我不确定是否可以安全地存储用户特定的数据HttpContext.Current.Items.
一个用例是从基础控制器传递用户信用OnActionExecuting(...)以用于Controller计算和显示Views; 我知道我应该使用ViewData这个,但是我对嵌套的部分视图有一些不一致的结果.
难道是正确的说,HttpContext.Current.Items[...]就是Controllers喜欢ViewData[...]就是意见?
我正在使用C#4.0,我需要对服务进行单元测试.服务中的函数返回一个类似于我预期的变量i的路径,这是我期望回来的路径.但是,当我运行此测试时,我得到HttpContext.Current为NULL的错误.我该怎么做才能解决这个问题,以便可以运行测试?
[TestMethod]
public void GetPathTest()
{
var expected = System.IO.Path.GetFullPath(HttpContext.Current.Server.MapPath("~/Certificates/"));
var path = _mockService.Setup(o => o.GetPath()).Returns(expected);
}
Run Code Online (Sandbox Code Playgroud) 因此,如果在全局启动内调用,则抛出HttpContext.Request
public HttpRequest get_Request()
{
if (this.HideRequestResponse)
{
throw new HttpException(SR.GetString("Request_not_available"));
}
return this._request;
}
Run Code Online (Sandbox Code Playgroud)
这实际上已记录在案
如果在HttpRequest对象不可用时尝试使用此属性,ASP.NET将引发异常.例如,在Global.asax文件的Application_Start方法中或在从Application_Start方法调用的方法中都是如此.那时还没有创建HTTP请求.
有没有办法检查HttpContext.Request是否处于可以检索而不抛出异常的状态?实际上我想写一个TryGetRequest帮助方法.
我已经设置了一些日志中间件,可以使用 HttpContext 获取和记录信息。
我需要将 HttpResponse.Body 的位置设置为 0 以读取整个流,但是,无论我尝试什么,它都会抛出“不支持指定的方法”并失败。
这对我来说很奇怪,因为 position 内置于 HttpResponse.Body 中,我之前成功使用过它。
我还尝试使用 HttpResponse.Body.Seek 获得相同的结果。
在这一点上我被卡住了,任何帮助将不胜感激。
更新:一旦我将 response.body 移动到新的内存流中,我就能够改变它的位置,但是,现在它返回一个空的主体。
public async Task Invoke(HttpContext context)
{
//Retrieve request & response
var request = context.Request;
var response = context.Response;
if (request.Path != "/")
{
var reqBody = request.Body;
var resBody = response.Body;
string path = request.Path;
string method = request.Method;
string queryString = HttpUtility.UrlDecode(request.QueryString.ToString());
int statusCode = context.Response.StatusCode;
var buffer = new byte[Convert.ToInt32(request.ContentLength)];
await request.Body.ReadAsync(buffer, 0, buffer.Length);
var reqBodyText = Encoding.UTF8.GetString(buffer); …Run Code Online (Sandbox Code Playgroud) 我在最近看到的一些生产登录代码中发现了这个...
HttpContext.Current.Trace.Write(query + ": " + username + ", " + password));
Run Code Online (Sandbox Code Playgroud)
...其中query是一个简短的SQL查询来获取匹配的用户.这会对性能产生什么影响吗?我认为它非常小.
此外,使用HTTP上下文,这种确切类型的跟踪的目的是什么?这些数据可以追溯到哪里?提前致谢!
有一个ashx文件,其中包含"ProcessRequest(HttpContext context)"自动触发的方法.何时以及如何被触发?另一个问题是,当我在这个文件中时,如何获取当前的QueryString?当我输入context.Request.QueryString"时,它表示它为空或为空地址有参数.
在我的AuthenticateRequest事件处理程序中,我设置了Thread的主体.这是我的IHttpModule的一部分:
public void Init(HttpApplication context)
{
context.AuthenticateRequest += AuthenticateRequest;
}
private void AuthenticateRequest(object sender, EventArgs e)
{
var principal = CreatePrincipal();
HttpContext.Current.User = principal;
}
Run Code Online (Sandbox Code Playgroud)
但我有一个程序集,不应该访问System.Web,所以我不能使用HttpContext.Current.User,但我需要访问当前主体.我的第一个想法是将我的方法改为:
System.Threading.Thread.CurrentPrincipal = HttpContext.Current.User = principal;
Run Code Online (Sandbox Code Playgroud)
并在需要时使用Thread.CurrentPrincipal.
但据我记得,在线程本地存储中存储请求特定内容是不安全的,因为多个线程可以处理相同的请求,所以我猜它与Thread.CurrentPrincipal相同.或不?
我已经打了好几个小时了,我很难过.我正在向MVC 5控制器发出ajax post请求,试图自动登录特定的预定义"超级"用户.在控制器方法中,我正在尝试以编程方式设置HttpContext.Current.User并进行身份验证,因此超级用户可以跳过手动登录的过程.对此的共识似乎就在这里,我实现了:
这似乎有效,直到我尝试使用自定义AuthorizeAttribute查看任何其他控制器方法.
控制器方法:
[HttpPost]
[AllowAnonymous]
public ActionResult Login(string username)
{
string password = ConfigurationManager.AppSettings["Pass"];
User user = service.Login(username, password);
var name = FormsAuthentication.FormsCookieName;
var cookie = Response.Cookies[name];
if (cookie != null)
{
var ticket = FormsAuthentication.Decrypt(cookie.Value);
if (ticket != null && !ticket.Expired)
{
string[] roles = (ticket.UserData as string ?? "").Split(',');
System.Web.HttpContext.Current.User = new GenericPrincipal(new FormsIdentity(ticket), roles);
}
}
//...processing result
return Json(result);
}
Run Code Online (Sandbox Code Playgroud)
上面的service.Login方法创建cookie:
FormsAuthentication.SetAuthCookie(cookieValue, false);
Run Code Online (Sandbox Code Playgroud)
虽然我正在设置具有Identity和IsAuthenticated的User,但下面的filterContext.HttpContext.User不是同一个用户.它本质上是空的,好像从未分配过,并且未经过身份验证.
public override void OnAuthorization(AuthorizationContext filterContext)
{
string[] userDetails = …Run Code Online (Sandbox Code Playgroud) httpcontext ×10
asp.net ×5
c# ×5
asp.net-mvc ×3
.net ×2
ashx ×1
c#-4.0 ×1
httpresponse ×1
performance ×1
signalr ×1
trace ×1
unit-testing ×1
viewdata ×1