Это правильный способ «переслать» запрос изображения с потоковой передачей? - PullRequest
0 голосов
/ 25 марта 2020

Я реализую контроллер API, который должен функционировать в качестве шлюза для получения изображений. Позже этот шлюз должен проверить, авторизован ли пользователь для получения изображения, но на данный момент реализована только потоковая передача изображения, и мой вопрос в том, что я не хочу реализовывать свой потоковый шлюз плохим способом: правильный способ сделать это или есть лучший способ?

В настоящее время это код:

    public IHttpActionResult Get(string objectId, string sessionId, string path)
    {
        var url = "An url to a jpeg or any other image";
        var copyOfStream = new MemoryStream();

        var request = WebRequest.Create(url);
        var getImageResponse = request.GetResponse();

        try
        {

            var stream = getImageResponse.GetResponseStream();
            stream.CopyTo(copyOfStream);
        }
        finally
        {
            getImageResponse.Close();
        }

        var response = new HttpResponseMessage(HttpStatusCode.OK)
        {
            Content = new StreamContent(copyOfStream)
        };

        var contentType = MimeMapping.GetMimeMapping(Path.GetExtension(".jpg"));
        response.Content.Headers.ContentType = new MediaTypeHeaderValue(contentType);

        return ResponseMessage(response);
    }

Есть предложения по улучшению?

1 Ответ

1 голос
/ 25 марта 2020

Я бы сделал это по-другому, чтобы избавиться от некоторых частей, которые довольно беспокоят:

  1. Одноразовые объекты оставлены нераспределенными и могут утечь.
  2. Двоичные данные изображения полностью загружены в память и подается оттуда
  3. ПРИМЕЧАНИЕ. Обратите внимание: текущая реализация всегда будет обслуживать 0 байт, поскольку вы не вызываете copyOfStream.Position = 0 до подачи ее в ответ
  4. Это чтение -all / write-all подход, который будет медленнее, чем «пишите, как вы читаете»

Итак, вот предлагаемое решение, которое:

  1. Использует HttpRequestMessage.RegisterForDispose расширение для зарегистрируйте одноразовые объекты для удаления после завершения текущего запроса,
  2. Записывает данные в поток ответов в виде фрагментов, когда они считываются с целевого веб-сайта (если платформа Web API работает таким образом, что весьма вероятно)

Надеюсь, это поможет:

    public IHttpActionResult Get(string objectId, string sessionId, string path)
    {
        var url = "An url to a jpeg or any other image";

        var request = WebRequest.Create(url);

        var getImageResponse = request.GetResponse();

        // Register the WebResponse for late disposal
        Request.RegisterForDispose(getImageResponse);

        Stream inputStream = getImageResponse.GetResponseStream();

        // Register the response stream for late disposal
        Request.RegisterForDispose(inputStream);

        // We haven't read anything from the wire yet:
        var response = new HttpResponseMessage(HttpStatusCode.OK)
        {
            Content = new StreamContent(inputStream)
        };

        var contentType = MimeMapping.GetMimeMapping(Path.GetExtension(".png"));
        response.Content.Headers.ContentType = new MediaTypeHeaderValue(contentType);

        return ResponseMessage(response);
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...