Asp.net web api WebAPI HttpContext在ContinueWith()中为Null=>;品尝
我只是想知道是否有人能解释一下这里发生了什么 给定API控制器上的此Post方法: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
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;
}