Я пытаюсь вызвать веб-сервис из моего веб-приложения на 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
?