MultipartFormDataStreamProvider and preserving current HttpContext

别说谁变了你拦得住时间么 提交于 2020-01-16 07:05:54

问题


I have a problem with the async file uploading feature of WebApi.

Currently I am able to save the file using the provider, but I then want to use a service (_myService) to log the filename of the file uploaded. Inside the service, it uses another service to get the current UserId. It does this by using the current HttpContext. Unfortunately the current HttpContext seems to be lost within the new task thread.

I tried to add TaskScheduler.FromCurrentSynchronizationContext() as the 2nd parameter of the task but this had no effect. Not really sure what that gives me. So I need some way of getting the Http context across to the new thread. How would I achieve this?

[ValidationFilter]
        public Task<FileUpModel> Upload([FromUri]int ReportType, [FromUri]string LocationDescription, string AdditionalInformation)
        {
            if (Request.Content.IsMimeMultipartContent())
            {
                var imagePath = HttpContext.Current.Server.MapPath("~/App_Data");

                var provider = new MyFormDataStreamProvider(imagePath);

                var task = Request.Content.ReadAsMultipartAsync(provider).ContinueWith(
                t =>
                {

                    if (t.IsFaulted || t.IsCanceled)
                        throw new HttpResponseException(HttpStatusCode.InternalServerError);

                    var fileInfo = provider.FileData.FirstOrDefault();
                    if (fileInfo == null)
                        throw new HttpResponseException(HttpStatusCode.InternalServerError);

                    // httpContext is lost here...
                    _myService.LogUploadedFile(fileInfo.LocalFileName);

                    var uploadModel = new FileUpModel { success = true };
                    return uploadModel;
                }, TaskScheduler.FromCurrentSynchronizationContext());

                return task;
            }
            else
            {
                throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotAcceptable, "This request is not properly formatted"));
            }            
        }

回答1:


I discovered a work around in the end, it doesn't look as clean as I would have liked. Basically, I keep a copy of the context in a separate variable and pass this into the closure. Not sure if this is best practise or not but it works!

 var currentHttpContext = HttpContext.Current;

        var task = Request.Content.ReadAsMultipartAsync(provider).ContinueWith(
        t =>
        {
            // Enquiry service requires access to authentication data which is retrieved via http context.
            // Not ideal but set the http context here so it available on the new thread.                    
            HttpContext.Current = currentHttpContext;

            if (t.IsFaulted || t.IsCanceled)
                throw new HttpResponseException(HttpStatusCode.InternalServerError);

            var fileInfo = provider.FileData.FirstOrDefault();
            if (fileInfo == null)
                throw new HttpResponseException(HttpStatusCode.InternalServerError);

            _myService.LogUploadedFile(fileInfo.LocalFileName);

            var uploadModel = new FileUpModel { success = true };
            return uploadModel;
        });

        return task;


来源:https://stackoverflow.com/questions/16823374/multipartformdatastreamprovider-and-preserving-current-httpcontext

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!