【问题标题】:Download mp3 file at browser through API .net core通过 API .net core 在浏览器上下载 mp3 文件
【发布时间】:2021-02-26 05:58:08
【问题描述】:

试图通过我创建的 API 在浏览器中下载 mp3 文件。但不是接收 mp3 文件。我不断收到 JSON 格式的响应。我已经从return-file-in-asp-net-core-web-api 的答案中提到过,但我仍然无法下载 mp3 文件。 有没有我忽略的错误,请帮忙?

这是我从 UI 下载的方法

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 { }
}

这是我从服务器下载mp3的api函数

 [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" }
          };
      }

这是我从浏览器和 Postman 得到的响应

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

【问题讨论】:

    标签: rest .net-core asp.net-core-webapi mp3 webclient


    【解决方案1】:

    因为返回值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);
        }
    

    【讨论】:

    • 嗨,Karney,我想我已经使用 CopyToAsync(memory) 传入了流。还是您的意思是从 WebClient 读取 Stream?
    • 是的,它通过File返回流,而不是字符串。
    • 哦,我知道你的意思。我已经测试了你建议的方式。但它仍然返回 JSON 格式而不是文件,谢谢你的帮助。我正在使用 Blazor,所以我正在考虑检查 blazor 中的 API 配置。
    • 可能是因为 blazor 的数据类型?
    • 这是由于 Blazor 有一个 API 响应包装器,我不得不将我的 API 放入异常中,这样它就不会将我的内容更改为 JSON。 :D 感谢您的帮助!
    【解决方案2】:

    我正在为此使用 Blazor。事实证明,Blazor APIReponse 中间件中有一个 API 响应包装器。我必须将我的 API 放入一个异常中,这样当我访问它时它就不会变成 JSON。终于成功了。

    以下是 Blazor 中的 APIReponse 包装器。

    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);
                                }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-04-15
      • 1970-01-01
      • 2018-08-03
      • 2018-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多