我有一个异步WebApi控制器,它在await块中调用Request.CreateResponse(HttStatusCode.Created, result)
时抛出一个StructureMapException,但仅在第一个请求期间抛出。 StructureMap正确解析所有构造函数依赖项,但行为就像请求结束后调用Request.CreateResponse
一样。在await块中使用Request.CreateResponse
是一个坏主意吗?这种策略可能带来哪些其他风险?
我使用以下NuGet包:
以下是代码:
public class EmailController : ApiController
{
private readonly ISaveEmailNotification _saveEmailNotification;
private readonly ISaveFile _saveFile;
public EmailController(ISaveEmailNotification saveEmailNotification, ISaveFile saveFile)
{
_saveEmailNotification = saveEmailNotification;
_saveFile = saveFile;
}
[HttpPost]
public async Task<HttpResponseMessage> SaveEmail(NotificationRequest model)
{
return await Task.Run(() =>
{
var emailResult = _saveEmailNotification.Execute(model);
var fileResult = _saveFile.Execute(model, emailResult);
return Request.CreateResponse(HttpStatusCode.Created, fileResult);
}
}
}
这是错误:
StructureMap.StructureMapException was unhandled by user code
HResult=-2146233088
Message=You cannot use the HttpContextLifecycle outside of a web request. Try the HybridLifecycle instead.
1.) Container.GetInstance(System.Web.HttpContextBase)
2.) Container.TryGetInstance(System.Web.HttpContextBase)
Source=StructureMap.Web
Title=You cannot use the HttpContextLifecycle outside of a web request. Try the HybridLifecycle instead.
StackTrace:
at StructureMap.Web.Pipeline.HttpContextLifecycle.findHttpDictionary() in c:\BuildAgent\work\996e173a8ceccdca\src\StructureMap.Web\Pipeline\HttpContextLifecycle.cs:line 57
at StructureMap.Web.Pipeline.HttpContextLifecycle.FindCache(ILifecycleContext context) in c:\BuildAgent\work\996e173a8ceccdca\src\StructureMap.Web\Pipeline\HttpContextLifecycle.cs:line 20
at StructureMap.BuildSession.ResolveFromLifecycle(Type pluginType, Instance instance) in c:\BuildAgent\work\996e173a8ceccdca\src\StructureMap\BuildSession.cs:line 102
at StructureMap.SessionCache.GetObject(Type pluginType, Instance instance, ILifecycle lifecycle) in c:\BuildAgent\work\996e173a8ceccdca\src\StructureMap\SessionCache.cs:line 88
at StructureMap.SessionCache.GetDefault(Type pluginType, IPipelineGraph pipelineGraph) in c:\BuildAgent\work\996e173a8ceccdca\src\StructureMap\SessionCache.cs:line 66
at StructureMap.Container.GetInstance(Type pluginType) in c:\BuildAgent\work\996e173a8ceccdca\src\StructureMap\Container.cs:line 335
at StructureMap.Container.TryGetInstance(Type pluginType) in c:\BuildAgent\work\996e173a8ceccdca\src\StructureMap\Container.cs:line 278
at StructureMap.Container.TryGetInstance[T]() in c:\BuildAgent\work\996e173a8ceccdca\src\StructureMap\Container.cs:line 289
at NotificationHubWeb.DependencyResolution.StructureMapDependencyScope.get_HttpContext() in C:\Users\Dave\Source\Workspaces\NotificationHub\Main\NotificationHubWeb\DependencyResolution\StructureMapDependencyScope.cs:line 68
at NotificationHubWeb.DependencyResolution.StructureMapDependencyScope.get_CurrentNestedContainer() in C:\Users\Dave\Source\Workspaces\NotificationHub\Main\NotificationHubWeb\DependencyResolution\StructureMapDependencyScope.cs:line 55
at NotificationHubWeb.DependencyResolution.StructureMapDependencyScope.DoGetInstance(Type serviceType, String key) in C:\Users\Dave\Source\Workspaces\NotificationHub\Main\NotificationHubWeb\DependencyResolution\StructureMapDependencyScope.cs:line 109
at Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance(Type serviceType, String key) in c:\Projects\CommonServiceLocator\main\Microsoft.Practices.ServiceLocation\ServiceLocatorImplBase.cs:line 49
答案 0 :(得分:0)
在我重写代码时,看起来在await块之外使用Request.CreateResponse
会在第一次使用时支持StructureMapException:
[HttpPost]
public async Task<HttpResponseMessage> SaveEmail(NotificationRequest model)
{
var taskResult await Task.Run(() =>
{
var emailResult = _saveEmailNotification.Execute(model);
return _saveFile.Execute(model, emailResult);
}
return Request.CreateResponse(HttpStatusCode.Created, taskResult);
}
现在,这看起来像赢家,但如果你能解释为什么在await块之外移动Request.CreateReponse
允许代码无误地运行,我会投票或宣布你是回答者。