WebApi在await块中调用request . createrresponse()有什么风险?

本文关键字:什么 createrresponse await request 调用 WebApi | 更新日期: 2023-09-27 18:15:30

我有一个异步WebApi控制器抛出StructureMapException时调用Request.CreateResponse(HttStatusCode.Created, result)在一个等待块,但只有在第一个请求。StructureMap可以正确解析所有构造函数依赖项,但其行为就像在请求结束后调用Request.CreateResponse一样。在等待块内使用Request.CreateResponse是一个坏主意吗?这种策略还可能带来哪些风险?

我使用以下NuGet包:

  • StructureMap 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'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

WebApi在await块中调用request . createrresponse()有什么风险?

看起来在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块可以让代码运行没有错误,我将投票给你或宣布你是答案。