Могу ли я сделать асинхронную запись из текущего httpcontext? - PullRequest
0 голосов
/ 16 апреля 2019

Я пытаюсь вызвать веб-сервис из моего веб-приложения на C #, который создает zip-файл на основе некоторых параметров, которые я отправляю, а затем возвращает zip-файл для загрузки клиенту.

Рабочий процесс выполняетсянапример:

  • Пользователь нажимает кнопку, появляется диалоговое окно с перечнем некоторых файлов, и они выбирают нужные ему файлы
  • Мы инициируем запрос к другому веб-серверу, на котором размещены файлызаархивировать их и вернуть их
  • Пользователь получает загруженный zip-файл в папку его загрузок

Я успешно смог выполнить этот процесс, но не так чисто и эффективнокак бы мне хотелось.Код размещен ниже.В основном, код не асинхронный, и мне действительно не нравится тот факт, что мне нужно скопировать весь ответ в текущий контекст.

public class GetZip : HttpTaskAsyncHandler
    {
        public override async Task ProcessRequestAsync(HttpContext context)
        {
            JavaScriptSerializer oSearlizer = new JavaScriptSerializer();

            object o = new
            {
                ...
            };

            string req = oSearlizer.Serialize(o);
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost:7071/api/get_zip");
            request.Method = "POST";
            request.ContentType = "application/json";
            using (Stream webStream = request.GetRequestStream())
            {
                using (StreamWriter streamWriter = new StreamWriter(webStream, Encoding.UTF8))
                {
                    streamWriter.Write(req);
                }
            }

            WebResponse webResponse = request.GetResponse();
            using (Stream webStream = webResponse.GetResponseStream())
            {
                if (webStream != null)
                {
                    using (BinaryReader responseReader = new BinaryReader(webStream))
                    {
                        byte[] byteResponse = ReadAllBytes(responseReader);
                        context.Response.Clear();
                        context.Response.Buffer = true;
                        context.Response.ContentType = "application/zip";
                        context.Response.AddHeader("content-disposition", "attachment;filename=test.zip"); // Save file         
                        context.Response.AddHeader("Content-Length", byteResponse.Length.ToString());
                        context.Response.Charset = "";
                        context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
                        context.Response.BinaryWrite(byteResponse);
                        context.Response.End();
                    }
                }
            }
        }
    }

Веб-служба, которую я вызываю, возвращает данные вследующим образом:

HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
                        response.Content = new ByteArrayContent(compressedBytes);
                        response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
                        response.Content.Headers.ContentDisposition.FileName = fileNameZip;
                        response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/zip");

То, что я действительно хотел бы сделать, это просто инициировать другой запрос непосредственно из HttpContext, чтобы ответ возвращался как текущий ответ HttpContext без создания нового запроса, получая ответ,и затем копирование данных в текущий HttpContext.

Примерно так:

public class GetZip : HttpTaskAsyncHandler
    {
        public override async Task ProcessRequestAsync(HttpContext context)
        {
            JavaScriptSerializer oSearlizer = new JavaScriptSerializer();

            object o = new
            {
                ...
            };

            string req = oSearlizer.Serialize(o);
            HttpContent content = new StringContent(req, Encoding.UTF8, "application/json");
            HttpClient client = new HttpClient();

            await client.PostAsync("http://localhost:7071/api/get_zip", content);
        }

Однако это не инициирует загрузку для клиента, поскольку с текущим * 1024 ничего не происходит*.Есть ли способ прикрепить текущий HttpContext к HttpClient, который я создаю, чтобы ответ шел в текущий контекст?Или есть какой-то способ получить HttpClient из текущего HttpContext?

...