Asp.net web api WebAPI HttpContext在ContinueWith()中为Null=>;品尝

Asp.net web api WebAPI HttpContext在ContinueWith()中为Null=>;品尝,asp.net-web-api,Asp.net Web Api,我只是想知道是否有人能解释一下这里发生了什么 给定API控制器上的此Post方法: public HttpResponseMessage PostImage() { var request = HttpContext.Current.Request; var c = SynchronizationContext.Current; var result = new HttpResponseMessage(HttpStatusCode.OK); if (Reques

我只是想知道是否有人能解释一下这里发生了什么

给定API控制器上的此Post方法:

public HttpResponseMessage PostImage()
{
    var request = HttpContext.Current.Request;
    var c = SynchronizationContext.Current;

    var result = new HttpResponseMessage(HttpStatusCode.OK);
    if (Request.Content.IsMimeMultipartContent())
    {            
        Request.Content.ReadAsMultipartAsync(new MultipartMemoryStreamProvider()).ContinueWith((task) =>
        {
            MultipartMemoryStreamProvider provider = task.Result;
            foreach (HttpContent content in provider.Contents)
            {
                Stream stream = content.ReadAsStreamAsync().Result;
                Image image = Image.FromStream(stream);
                var uploadFileName = content.Headers.ContentDisposition.FileName;

                var requestInside = HttpContext.Current.Request;  // this is always null    

                string filePath = Path.Combine(HostingEnvironment.MapPath(ConfigurationManager.AppSettings["UserFilesRootDir"]), userprofile.UserCode);

                //string[] headerValues = (string[])Request.Headers.GetValues("UniqueId");

                string fileName = userprofile.UserCode + ".jpg";

                string fullPath = Path.Combine(filePath, fileName);

                image.Save(fullPath);
            }
        });
        return result;
    }
}
为什么
var requestInside=HttpContext.Current.Request是否为空

我已检查了所有相关设置:

<compilation debug="true" targetFramework="4.5">
...

<httpRuntime targetFramework="4.5"

...

ContinueWith
不能保证在同一线程上运行,因此同步上下文可能会丢失。您可以使用参数
TaskScheduler.current
更改调用以指定在当前线程上继续

如果您使用wait/async模式,那么一旦等待操作完成,它将在resume上自动捕获当前同步上下文。这是通过在绑定到该上下文的同一线程上恢复操作来完成的。IMHO的另一个好处是代码看起来更干净

您可以将代码更改为使用该模式的代码。除了使用async/await,我没有对它做任何其他更改

public异步任务PostImage()
{
var request=HttpContext.Current.request;
var c=SynchronizationContext.Current;
var结果=新的HttpResponseMessage(HttpStatusCode.OK);
if(Request.Content.IsMimeMultipartContent())
{
MultipartMemoryStreamProvider provider=wait Request.Content.ReadAsMultipartAsync(新的MultipartMemoryStreamProvider());
foreach(provider.Contents中的HttpContent内容)
{
Stream=等待内容。ReadAsStreamAsync();
Image=Image.FromStream(流);
var uploadFileName=content.Headers.ContentDisposition.FileName;
var requestInside=HttpContext.Current.Request;//此值始终为空
字符串filePath=Path.Combine(HostingEnvironment.MapPath(ConfigurationManager.AppSettings[“userfilerootdir”)、userprofile.UserCode);
//string[]headerValues=(string[])Request.Headers.GetValues(“UniqueId”);
字符串文件名=userprofile.UserCode+“.jpg”;
字符串fullPath=Path.Combine(filePath,fileName);
image.Save(完整路径);
}
}
返回结果;
}

我很好奇。为什么不使用async/await操作符,以便在异步方法完成后恢复执行时捕获请求上下文?因此,标记方法签名
public async Task PostImage
当然,我仍在编写这段代码,也会这样做,但只是好奇而已。我在
ContinueWith
上更新了我的答案,以及您可能如何让它仅在该更改下工作。我最初的假设(基于ContinueWith)确实是有意义的这是正确的。谢谢你,伊戈尔。
public async Task<HttpResponseMessage> PostImage()
{
    var request = HttpContext.Current.Request;
    var c = SynchronizationContext.Current;

    var result = new HttpResponseMessage(HttpStatusCode.OK);
    if (Request.Content.IsMimeMultipartContent())
    {
        MultipartMemoryStreamProvider provider = await Request.Content.ReadAsMultipartAsync(new MultipartMemoryStreamProvider());
        foreach (HttpContent content in provider.Contents)
        {
            Stream stream = await content.ReadAsStreamAsync();
            Image image = Image.FromStream(stream);
            var uploadFileName = content.Headers.ContentDisposition.FileName;

            var requestInside = HttpContext.Current.Request;  // this is always null    

            string filePath = Path.Combine(HostingEnvironment.MapPath(ConfigurationManager.AppSettings["UserFilesRootDir"]), userprofile.UserCode);

            //string[] headerValues = (string[])Request.Headers.GetValues("UniqueId");

            string fileName = userprofile.UserCode + ".jpg";

            string fullPath = Path.Combine(filePath, fileName);

            image.Save(fullPath);
        }
    }
    return result;
}