WebApi 在 await 块中调用 Request.CreateResponse() 会带来什么风险?
What risks does WebApi incur when calling Request.CreateResponse() inside await block?
我有一个异步 WebApi 控制器,它在等待块内调用 Request.CreateResponse(HttStatusCode.Created, result)
时抛出 StructureMapException,但仅在第一个请求期间。 StructureMap 正确解析所有构造函数依赖性,但表现得好像 Request.CreateResponse
在请求结束后被调用。在 await 块中使用 Request.CreateResponse
只是一个坏主意吗?该策略可能会带来哪些其他风险?
我正在使用以下 NuGet 包:
- 结构图 3.1.6.186
- StructureMap.Web 3.1.0.133
- StructureMap.WebApi2 3.0.4.125
- WebActivator 2.0.5
代码如下:
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\work6e173a8ceccdca\src\StructureMap.Web\Pipeline\HttpContextLifecycle.cs:line 57
at StructureMap.Web.Pipeline.HttpContextLifecycle.FindCache(ILifecycleContext context) in c:\BuildAgent\work6e173a8ceccdca\src\StructureMap.Web\Pipeline\HttpContextLifecycle.cs:line 20
at StructureMap.BuildSession.ResolveFromLifecycle(Type pluginType, Instance instance) in c:\BuildAgent\work6e173a8ceccdca\src\StructureMap\BuildSession.cs:line 102
at StructureMap.SessionCache.GetObject(Type pluginType, Instance instance, ILifecycle lifecycle) in c:\BuildAgent\work6e173a8ceccdca\src\StructureMap\SessionCache.cs:line 88
at StructureMap.SessionCache.GetDefault(Type pluginType, IPipelineGraph pipelineGraph) in c:\BuildAgent\work6e173a8ceccdca\src\StructureMap\SessionCache.cs:line 66
at StructureMap.Container.GetInstance(Type pluginType) in c:\BuildAgent\work6e173a8ceccdca\src\StructureMap\Container.cs:line 335
at StructureMap.Container.TryGetInstance(Type pluginType) in c:\BuildAgent\work6e173a8ceccdca\src\StructureMap\Container.cs:line 278
at StructureMap.Container.TryGetInstance[T]() in c:\BuildAgent\work6e173a8ceccdca\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
看起来在 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);
}
现在,这看起来像是赢家,但如果你能解释为什么将 Request.CreateReponse
移到 await 块之外允许代码无误地 运行,我将投票给你或宣布你为回答者.
我有一个异步 WebApi 控制器,它在等待块内调用 Request.CreateResponse(HttStatusCode.Created, result)
时抛出 StructureMapException,但仅在第一个请求期间。 StructureMap 正确解析所有构造函数依赖性,但表现得好像 Request.CreateResponse
在请求结束后被调用。在 await 块中使用 Request.CreateResponse
只是一个坏主意吗?该策略可能会带来哪些其他风险?
我正在使用以下 NuGet 包:
- 结构图 3.1.6.186
- StructureMap.Web 3.1.0.133
- StructureMap.WebApi2 3.0.4.125
- WebActivator 2.0.5
代码如下:
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\work6e173a8ceccdca\src\StructureMap.Web\Pipeline\HttpContextLifecycle.cs:line 57
at StructureMap.Web.Pipeline.HttpContextLifecycle.FindCache(ILifecycleContext context) in c:\BuildAgent\work6e173a8ceccdca\src\StructureMap.Web\Pipeline\HttpContextLifecycle.cs:line 20
at StructureMap.BuildSession.ResolveFromLifecycle(Type pluginType, Instance instance) in c:\BuildAgent\work6e173a8ceccdca\src\StructureMap\BuildSession.cs:line 102
at StructureMap.SessionCache.GetObject(Type pluginType, Instance instance, ILifecycle lifecycle) in c:\BuildAgent\work6e173a8ceccdca\src\StructureMap\SessionCache.cs:line 88
at StructureMap.SessionCache.GetDefault(Type pluginType, IPipelineGraph pipelineGraph) in c:\BuildAgent\work6e173a8ceccdca\src\StructureMap\SessionCache.cs:line 66
at StructureMap.Container.GetInstance(Type pluginType) in c:\BuildAgent\work6e173a8ceccdca\src\StructureMap\Container.cs:line 335
at StructureMap.Container.TryGetInstance(Type pluginType) in c:\BuildAgent\work6e173a8ceccdca\src\StructureMap\Container.cs:line 278
at StructureMap.Container.TryGetInstance[T]() in c:\BuildAgent\work6e173a8ceccdca\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
看起来在 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);
}
现在,这看起来像是赢家,但如果你能解释为什么将 Request.CreateReponse
移到 await 块之外允许代码无误地 运行,我将投票给你或宣布你为回答者.