来源:https://gist.github.com/sniffdk/7600822
以下代码由http请求之外的活动运行,因此我需要模拟http上下文。
我像这样嘲笑了http上下文:
IO
我将此public class GetUmbracoServiceMockedHttpContext : IGetUmbracoService
{
private UmbracoHelper umbracoHelper;
public T GetService<T>()
where T : IService
{
UmbracoContext context = UmbracoContext.Current;
if (context == null)
{
var dummyHttpContext = new HttpContextWrapper(new HttpContext(new SimpleWorkerRequest("blah.aspx", "", new StringWriter())));
context = UmbracoContext.EnsureContext(
dummyHttpContext,
ApplicationContext.Current,
new WebSecurity(dummyHttpContext, ApplicationContext.Current),
UmbracoConfig.For.UmbracoSettings(),
UrlProviderResolver.Current.Providers,
false);
}
var serviceTypeProperty = context.Application.Services
.GetType()
.GetProperties()
.SingleOrDefault(x => x.PropertyType == typeof(T));
if (serviceTypeProperty == null)
{
return default(T);
}
return (T)serviceTypeProperty
.GetValue(context.Application.Services);
}
}
注入控制器并调用:
IGetUmbracoService service
...发生以下错误。
System.ArgumentNullException:值不能为null。参数名称: System.Web.HttpContextWrapper..ctor中的httpContext(HttpContext httpContext) Umbraco.Web.SingletonHttpContextAccessor.get_Value()at Umbraco.Web.RequestLifespanMessagesFactory.Get()at Umbraco.Core.Services.ContentService.SaveAndPublishDo(IContent content,Int32 userId,Boolean raiseEvents)at Umbraco.Core.Services.ContentService.Umbraco.Core.Services.IContentServiceOperations.SaveAndPublish(IContent content,Int32 userId,Boolean raiseEvents)at Umbraco.Core.Services.ContentService.SaveAndPublishWithStatus(IContent content,Int32 userId,Boolean raiseEvents)
如何在不使用frowned upon HttpContext.Current = ...
的情况下模拟http上下文?
我认为相关问题来自:
RequestLifespanMessagesFactory.cs
反过来调用这个的实现:
答案 0 :(得分:1)
我与Umbraco合作,从控制台应用程序运行它,然后使用Umbraco API调用Umbraco。 我相信我是基于这个项目:https://github.com/sitereactor/umbraco-console-example
可能有用。
答案 1 :(得分:0)
感谢user369142。这就是最终的工作:
我还必须确保我没有在SaveandPublish调用上引发任何事件......因为HttpContext期望在上下文中注册消息但我们不会模拟任何事件......如果你确保引发事件是错误的,它会跳过关心它的代码。
public class CustomSingletonHttpContextAccessor : IHttpContextAccessor
{
public HttpContextBase Value
{
get
{
HttpContext context = HttpContext.Current;
if (context == null)
{
context = new HttpContext(new HttpRequest(null, "http://mockurl.com", null), new HttpResponse(null));
}
return new HttpContextWrapper(context);
}
}
}
public class CustomRequestLifespanMessagesFactory : IEventMessagesFactory
{
private readonly IHttpContextAccessor _httpAccessor;
public CustomRequestLifespanMessagesFactory(IHttpContextAccessor httpAccessor)
{
if (httpAccessor == null)
{
throw new ArgumentNullException("httpAccessor");
}
_httpAccessor = httpAccessor;
}
public EventMessages Get()
{
if (_httpAccessor.Value.Items[typeof(CustomRequestLifespanMessagesFactory).Name] == null)
{
_httpAccessor.Value.Items[typeof(CustomRequestLifespanMessagesFactory).Name] = new EventMessages();
}
return (EventMessages)_httpAccessor.Value.Items[typeof(CustomRequestLifespanMessagesFactory).Name];
}
}
public class CustomBootManager : WebBootManager
{
public CustomBootManager(UmbracoApplicationBase umbracoApplication)
: base(umbracoApplication)
{
}
protected override ServiceContext CreateServiceContext(DatabaseContext dbContext, IDatabaseFactory dbFactory)
{
//use a request based messaging factory
var evtMsgs = new CustomRequestLifespanMessagesFactory(new CustomSingletonHttpContextAccessor());
return new ServiceContext(
new RepositoryFactory(ApplicationCache, ProfilingLogger.Logger, dbContext.SqlSyntax, UmbracoConfig.For.UmbracoSettings()),
new PetaPocoUnitOfWorkProvider(dbFactory),
new FileUnitOfWorkProvider(),
new PublishingStrategy(evtMsgs, ProfilingLogger.Logger),
ApplicationCache,
ProfilingLogger.Logger,
evtMsgs);
}
}
public class CustomUmbracoApplication : Umbraco.Web.UmbracoApplication
{
...
protected override IBootManager GetBootManager()
{
return new CustomBootManager(this);
}
...
}