Скачать mp3 файл в браузере через ядро ​​API .net

Пытался загрузить mp3-файл в браузере через созданный мной API. Но вместо получения mp3 файла. Я продолжаю получать ответ в формате JSON. Я ссылался на ответ в return-file-in-asp-net- core-web-api, но все равно не могу скачать mp3 файл. Есть ли какая-то ошибка, которую я упустил из виду, пожалуйста, помогите?

Это мой метод загрузки из пользовательского интерфейса

void DownloadRecording(RecordingHistory voicehistory)
{
      try
      {
          using (var client = new WebClient())
          {
              client.DownloadFile("https://2d489fd863a2.ngrok.io/api/download/" + voicehistory.RecordingId + ".mp3", voicehistory.RecordingId + ".mp3");
          }

      }
      catch { }
}

Это моя функция API для загрузки mp3 с сервера.

 [HttpGet("download/{recordingFile}")]
 public async Task<IActionResult> DownloadVoiceRecording(string recordingFile)
 {
      string filePath = Directory.GetCurrentDirectory() + @"\audio\Processed\" + recordingFile;
      var memory = new MemoryStream();
      using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
      {
           await stream.CopyToAsync(memory);
      }
      memory.Position = 0;
      var types = GetMimeTypes();
      var ext = Path.GetExtension(filePath).ToLowerInvariant();

      return File(filePath, types[ext], recordingFile);
      }

      private Dictionary<string, string> GetMimeTypes()
      {
          return new Dictionary<string, string>
          {
              {".mp3", "audio/mpeg"},
              {".wav","audio/wav" }
          };
      }

Это ответ, который я получаю от браузера и почтальона

{
    "Version": "2.0.0.0",
    "StatusCode": 200,
    "Message": "Status 200 OK",
    "Result":"��@� ... ... /// A lot of random symbol here
}

person J.J    schedule 14.11.2020    source источник


Ответы (2)


Поскольку первый параметр возвращаемого значения File относится к типу Stream, необходимо передать memory.

[HttpGet("download/{recordingFile}")]
    public async Task<IActionResult> DownloadVoiceRecording(string recordingFile)
    {
        
        string filePath = Directory.GetCurrentDirectory() + @"\audio\Processed\" + recordingFile;
        var memory = new MemoryStream();
        using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
        {
            await stream.CopyToAsync(memory);
        }
        memory.Position = 0;
        var types = GetMimeTypes();
        var ext = Path.GetExtension(filePath).ToLowerInvariant();
        return File(memory, types[ext], recordingFile);
    }
person Karney.    schedule 16.11.2020
comment
Привет, Карни, я думаю, что уже прошел поток, используя CopyToAsync (память). Или вы имеете в виду читать поток из WebClient? - person J.J; 16.11.2020
comment
Да, он возвращает поток через File, а не строку. - person Karney.; 17.11.2020
comment
о, я знаю, что ты имеешь в виду. Я проверил способ, который вы предложили. Но он по-прежнему возвращает мне формат JSON вместо файла, кстати, спасибо за помощь. Я использую Blazor, поэтому думаю проверить конфигурацию API в blazor. - person J.J; 18.11.2020
comment
Может быть из-за типа данных blazor? - person Karney.; 18.11.2020
comment
Это произошло из-за того, что у Blazor есть оболочка API Response, мне пришлось поместить мой API в исключение, чтобы он не изменил мой контент в JSON. :D Спасибо за вашу помощь! - person J.J; 18.11.2020

Я использую Blazor для этого. Оказывается, в промежуточном программном обеспечении Blazor APIReponse была оболочка ответа API. Мне пришлось поместить свой API в исключение, чтобы он не превратился в JSON при доступе к нему. Это работает, наконец.

Ниже представлена ​​оболочка APIReponse в Blazor.

var formattedRequest = await FormatRequest(request);
                    var originalBodyStream = httpContext.Response.Body;

                    using (var responseBody = new MemoryStream())
                    {
                        try
                        {
                            string responseBodyContent = null;

                            var response = httpContext.Response;

                            if (new string[] { "/api/localization", "/api/data", "/api/externalauth", "/api/download" }.Any(e => request.Path.StartsWithSegments(new PathString(e.ToLower()))))
                                await _next.Invoke(httpContext);
                            else
                            {
                                response.Body = responseBody;

                                await _next.Invoke(httpContext);

                                //wrap response in ApiResponse
                                if (httpContext.Response.StatusCode == Status200OK)
                                {
                                    responseBodyContent = await FormatResponse(response);
                                    await HandleSuccessRequestAsync(httpContext, responseBodyContent, Status200OK);
                                }
                                else
                                    await HandleNotSuccessRequestAsync(httpContext, httpContext.Response.StatusCode);
                            }
person J.J    schedule 18.11.2020