我正在寻找尽可能全面的模拟替换和HttpContext我的应用程序中的ASP.NET包装器.全面的模拟替换可能会大大提高ASP.NET Web应用程序的可测试性,而无需将每个应用程序迁移到更易测试的框架(如MVC).
我最感兴趣的是在HttpContext包装器和模拟框架中看到的一些功能包括:
.Session)..Application)..Items).Server.MapPath).User用于验证身份验证/授权规则的标识和主体(例如).AllErrors用于测试HttpModules和中的错误解决方案的集合Global.asax.我考虑过编写自己的界面,包装和模拟; 但是,我相信这一点必须已经存在.各种模拟框架对于第一次吸收来说有点压倒性.
HttpContext你会推荐什么是最全面的包装和模拟?
我们希望将我们的项目从ASP.NET MVC 2升级到3.我们的大多数测试都成功了,但有些测试失败了ValueProviderFactories.Factories.GetValueProvider(context).
这是一个简单的测试类,用于解决问题.
[TestFixture]
public class FailingTest
{
[Test]
public void Test()
{
var type = typeof(string);
// any controller
AuthenticationController c = new AuthenticationController();
var httpContext = new Mock<HttpContextBase>();
var context = c.ControllerContext = new ControllerContext(httpContext.Object, new RouteData(), c);
IModelBinder converter = ModelBinders.Binders.GetBinder(type);
var bc = new ModelBindingContext
{
ModelName = "testparam",
ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, type),
ValueProvider = ValueProviderFactories.Factories.GetValueProvider(context)
};
Console.WriteLine(converter.BindModel(context, bc));
}
}
Run Code Online (Sandbox Code Playgroud)
异常"对象引用未设置为对象的实例." ValueProviderFactories.Factories.GetValueProvider(context)被叫时被抛出.stacktrace看起来像这样:
Microsoft.Web.Infrastructure.dll!Microsoft.Web.Infrastructure.DynamicValidationHelper.ValidationUtility.CollectionReplacer.GetUnvalidatedCollections(System.Web.HttpContext context) + 0x23 bytes
Microsoft.Web.Infrastructure.dll!Microsoft.Web.Infrastructure.DynamicValidationHelper.ValidationUtility.GetUnvalidatedCollections(System.Web.HttpContext context, out System.Collections.Specialized.NameValueCollection …Run Code Online (Sandbox Code Playgroud) 这里的帖子中有人评论说在使用MVC时不应该使用HttpContext.Current,而是应该使用ControllerBase.ControllerContext.在某些方面,这是有道理的,但在其他方面却没有.
例如,ControllerContext是一个实例变量,所以在我想引用的所有地方,比如我的Session变量,我需要有一个对Controller的引用?为什么我们"不应该"在MVC中使用HttpContext.Current,当你还可以的时候?是否有一个"适当的"MVC"方式"来获取我的Session对象而无需引用Controller?
我知道测试方面,它更好的原因在许多其他地方说明,但我正在研究一个管理Session变量和引用HttpContext.Current的项目,我想知道是否有更好的方法来获取Session对象没有传递对控制器的引用.
我正在阅读一篇关于HttpContext和CallContext的文章,看看线程敏捷性.这是什么意思?
我正在尝试将 Razor 视图呈现为来自托管服务的字符串。通过使用,IRazorViewEngine我可以使用如下所示的方式将视图呈现为字符串:
_viewEngine.FindView(actionContext, viewName, false);
var viewDictionary = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary())
{
Model = model
};
var viewContext = new ViewContext(
actionContext,
viewResult.View,
viewDictionary,
new TempDataDictionary(actionContext.HttpContext, _tempDataProvider),
sw,
new HtmlHelperOptions()
);
viewContext.RouteData = httpContext.GetRouteData(); //set route data here
await viewResult.View.RenderAsync(viewContext);
Run Code Online (Sandbox Code Playgroud)
但是,当Controller由于缺少而没有从 a 调用时,这会崩溃HttpContext。我尝试手动构建 HttpContext,但在 Microsoft Mvc 代码深处遇到许多错误和空异常,这极难调试。我尝试过像RazorLight这样的库,它不适合我的需求,因为它不能正确支持@inject指令。我认为我最好的解决方案是尝试模拟一个假的 HttpContext/ControllerContext 以传递给本机 ViewEngine。但是,当我创建一个 new 时DefaultHttpContext,我在此处得到一个 NullReferenceException ,但是很难跟踪代码并找到它的来源。
有没有办法创建一个新的 HttpContext?
我知道在 asp.net-core 2.2 中,我可以按如下方式获取操作名称:
ControllerContext.ActionDescriptor.ActionName
Run Code Online (Sandbox Code Playgroud)
但我正在寻找一种方法来获取 asp.net-core 2.2 中当前请求/页面的控制器名称
我将不胜感激任何指南。
谢谢
我想在我的ASP.NET应用程序中运行"后台作业"(定期,作为单独的线程).我需要主机名(DNS名称或IP)来完成我的任务.问题是HttpContext.Current这里可能没有(它的NULL).
有没有办法让主机名不使用HttpContext.Current.Request.Url.Host.
我们有一个依赖于的类HttpContext.我们已经实现了这样:
public SiteVariation() : this(new HttpContextWrapper(HttpContext.Current))
{
}
public SiteVariation(HttpContextBase context)
{}
Run Code Online (Sandbox Code Playgroud)
现在我想要做的是实例化SiteVariation类Unity,所以我们可以创建一个构造函数.但我不知道如何HttpContextWrapper(HttpContext.Current))在配置方式中在Unity中配置这个新功能.
ps这是我们使用的配置方式
<type type="Web.SaveRequest.ISaveRequestHelper, Common" mapTo="Web.SaveRequest.SaveRequestHelper, Common" />
Run Code Online (Sandbox Code Playgroud) 我已经开始使用Simple Injector作为我的DI容器(主要是出于性能原因:如果有人有建议,请告诉我),但我编写的一些类使用HttpContextBase作为构造函数参数.我现在已经解决了从构造函数中删除它并创建一个Property,如下所示:
public HttpContextBase HttpContext
{
get
{
if (null == _httpContext)
_httpContext = new HttpContextWrapper(System.Web.HttpContext.Current);
return _httpContext;
}
set
{
_httpContext = value;
}
}
Run Code Online (Sandbox Code Playgroud)
但我不喜欢这个解决方案...任何建议?
我研究了如何在 .NET Core 中创建 HttpContext。然后我发现有一个类HttpContextFactory,它创建对象并将其分配HttpContext给类HttpContext的属性HttpContextAccessor。为了在我们的代码中使用 HttpContext 对象,我们将 IHttpContextAccessor 注入到需要该对象的类的构造函数中。
当我查看 HttpContextAccessor 的实现时,显然它的 HttpContext 属性从私有AsyncLocal变量获取 HttpContext 对象值,后来 HttpContextAccessor 被注册为Singleton。
https://github.com/aspnet/AspNetCore/blob/master/src/Http/Http/src/HttpContextAccessor.cs
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Threading;
namespace Microsoft.AspNetCore.Http
{
public class HttpContextAccessor : IHttpContextAccessor
{
private static AsyncLocal<HttpContextHolder> _httpContextCurrent = new AsyncLocal<HttpContextHolder>();
public HttpContext HttpContext
{
get
{ …Run Code Online (Sandbox Code Playgroud) httpcontext ×10
asp.net ×5
c# ×5
asp.net-core ×2
asp.net-mvc ×2
controller ×2
.net ×1
.net-core ×1
hostname ×1
httprequest ×1
mocking ×1
threadpool ×1
unit-testing ×1
wrapper ×1