Асинхронная задача ActionMethod контроллера ASP.NET Core 2 FileResult› возвращает HttpresponseMessage

ОБНОВЛЕНИЕ: Как я уже упоминал, я изменил свой метод действий, но безуспешно. Посмотреть скриншоты

введите здесь описание изображения

Результат один и тот же:

введите здесь описание изображения

Кратко о моей проблеме: все в dot net core 2.0. У меня есть WebAPI (отдельный проект) и его контроллер (разговор с SQL Server). Мое клиентское приложение - это веб-приложение ASP.NET Core MVC, метод действия его контроллера БУДЕТ возвращать файл. В моем случае поток байтов. Когда я открываю файл, который я загрузил из браузера, в котором запущено мое клиентское приложение, файл похож на некоторый HttpResponseMessage, завернутый в формат стиля JSON.


Контроллер API

[Route("api/[controller]")]
public class GasDownloadController : Controller
{
    private readonly IGasesRepository _repository;

    public GasDownloadController(IGasesRepository repository)
    {
        _repository = repository;
    }

    [HttpGet]
    public HttpResponseMessage Export([FromQuery] Gas gas)
    {
        var item = _repository.GetGasesService(gas);

        byte[] outputBuffer = null;

        using (MemoryStream tempStream = new MemoryStream())
        {
            using (StreamWriter writer = new StreamWriter(tempStream))
            {
                FileWriter.WriteDataTable(item, writer, true);
            }
            outputBuffer = tempStream.ToArray();
        }
        HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
        result.Content = new ByteArrayContent(outputBuffer);
        result.Content.Headers.ContentType = new MediaTypeHeaderValue("text/csv");
        result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = $"ENVSdata.csv" };

        return result;
    }
}

Вспомогательный класс

public class FileWriter
{
    public static void WriteDataTable(DataTable sourceTable, TextWriter writer, bool includeHeaders)
    {
        if (includeHeaders)
        {
            writer.WriteLine("sep=,");
            IEnumerable<string> headerValues = sourceTable.Columns
                .OfType<DataColumn>()
                .Select(column => QuoteValue(column.ColumnName));
            writer.WriteLine(String.Join(",", headerValues));
        }

        IEnumerable<String> items = null;

        foreach (DataRow row in sourceTable.Rows)
        {
            items = row.ItemArray.Select(o => QuoteValue(o?.ToString() ?? String.Empty));
            writer.WriteLine(String.Join(",", items));
        }

        writer.Flush();
    }
    private static string QuoteValue(string value)
    {
        return String.Concat("\"",
            value.Replace("\"", "\"\""), "\"");
    }
}

Контроллер MVC

public class DownloadsController : Controller
{
    private IGasesRepository _repository;

    public DownloadsController(IGasesRepository repository)
    {
        _repository = repository;
    }

    [HttpGet]
    public ActionResult Index()
    {
        return View();
    }


    [HttpPost]
    public async Task<FileResult> GetFile(Gas inputGas)
    {
        var model = await _repository.GasDownloads(inputGas);
        return File(model, "text/csv", "data.csv");
    }
}

Репозиторий

public class GasesRepository : IGasesRepository
{
    public IEnumerable<Gas> Gases { get; set; }
    public byte[] CsvBytes { get; set; }

    private string BaseGasApiUrl = "http://localhost:XXXX";
    private string BaseDwnlApiUrl = "http://localhost:XXXX";

    public async Task<IEnumerable<Gas>> GasService(Gas gasCompound)
    {
       //code omitted for brewity
    }


    public async Task<byte[]> GasDownloads(Gas gasCompound)
    {
        UriBuilder builder = new UriBuilder(BaseDwnlApiUrl);
        builder.Query =
            $"XXXXX";

        using (var client = new HttpClient())
        {
            client.BaseAddress = new Uri(BaseDwnlApiUrl);
            client.DefaultRequestHeaders.Accept.Clear();

            try
            {
                HttpResponseMessage responseMessage = await client.GetAsync(builder.Uri);

                if (responseMessage.IsSuccessStatusCode)
                {
                    var apiResult = responseMessage.Content.ReadAsByteArrayAsync().Result;

                    CsvBytes = apiResult;
                }
                else
                    return null;
            }
            catch (HttpRequestException downloadRequestException)
            {
                throw new HttpRequestException(downloadRequestException.Message);
            }
            catch (ArgumentNullException argsNullException)
            {
                throw new ArgumentNullException(argsNullException.Message);
            }
        }
        return CsvBytes;
    }
}

РЕЗУЛЬТАТ

Итак, когда я открываю файл (например, Excel), загруженный моим браузером, это файл CSV, но вместо столбцов и строк и данных в нем это всего лишь

    {
  "version": {
    "major": 1,
    "minor": 1,
    "build": -1,
    "revision": -1,
    "majorRevision": -1,
    "minorRevision": -1
  },
  "content": {
    "headers": [
      {
        "key": "Content-Type",
        "value": [
          "text\/csv"
        ]
      },
      {
        "key": "Content-Disposition",
        "value": [
          "attachment; filename=data.csv"
        ]
      }
    ]
  },
  "statusCode": 200,
  "reasonPhrase": "OK",
  "headers": [

  ],
  "requestMessage": null,
  "isSuccessStatusCode": true
}

Что я уже пробовал:

Если я отлаживаю, я вижу, что получаю допустимый/действительный массив байтов, но каким-то образом происходит какое-то волшебство, или он настолько очевиден и велик, что я не вижу леса за деревьями?

Я попытался изменить метод Action контроллера MVC, чтобы он возвращал множество возможных типов вещей (IActionResult, IHttpResponse, FileContentResult и т. д.).

У меня был тот же проект в MVC 5, и без проблем я получил действительный CSV-файл с моими строками и столбцами данных.

Любая помощь будет принята с благодарностью!


person ystvan    schedule 02.10.2017    source источник
comment
@Nkosi, пожалуйста, посмотрите мои правки, почему я думаю, что это не дубликат, и ваш ответ stackoverflow.com/a/42460443/8162054 не решил мою проблему   -  person ystvan    schedule 03.10.2017
comment
Принятый ответ @Nkosi указывает, что вам нужно изменить GasDownloadController.Export, а не DownloadsController.GetFile.   -  person Kirk Larkin    schedule 03.10.2017
comment
@KirkLarkin мой плохой! Я изменил, как было предложено, и могу с радостью подтвердить, что он отлично работает! Большое спасибо!   -  person ystvan    schedule 03.10.2017
comment
как было предложено meta.stackoverflow.com/a/265737/8162054, я не буду удалять свой вопрос, хотя он глубоко дублирует . Спасибо всем!   -  person ystvan    schedule 03.10.2017