首页 > 解决方案 > How to download file with certain name, set in .NET Core controller method, using Vue.js?

问题描述

I have defined an endpoint which returns a file to my front-end project. The endpoint is shown below:

[HttpGet("{shipmentId:int}/pod")]
public async Task<IActionResult> GetShipmentPodAsync([FromRoute] int shipmentId)
{
   try
   {
      var result = await QueryBus
                    .SendAsync<GetShipmentPodQuery, PodFile>(
                        new GetShipmentPodQuery
                        {
                           ShipmentId = shipmentId
                        });

      return File(result.Content, result.Type, result.FileName);
   }
   catch (Exception e)
   {
      // ToDo: Handle exception in proper way
      return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
   }
}

The following function is responsible for communication with mentioned endpoint:

  async getPodFile(shipmentId) {
    const resource = `shipment/${shipmentId}/pod`;
    await client.getFile(resource)
      .then((result) => {
        const fileUrl = window.URL.createObjectURL(new Blob([result.data]));
        const a = document.createElement('a');
        document.body.appendChild(a);
        a.style = 'display: none';
        a.href = fileUrl;
        a.download = `test.pdf`;
        a.click();
        window.URL.revokeObjectURL(fileUrl);
        document.body.removeChild(a);
      });
  },

I would like to use file name returned from my API, but i have no idea how to access it after receiving a response (I've tried to log a response object, but found no field like "filename"). How to use name, taken from the server instead of the hard-coded one?

标签: javascriptc#vue.js.net-coredownload

解决方案


我找到了解决方案 - CORS 阻止了包含文件名的标头。我必须将 WithExposedHeaders 添加到我的 CORS 配置中:

        private const string ContentDispositionHeaderName = "Content-Disposition";

        internal static IServiceCollection ConfigureResourceSharing(this IServiceCollection services,
            IConfiguration configuration)
        {
            var originsContainer = configuration
                .GetSection(AllowedOriginsSectionName)
                .Get<ICollection<string>>();

            return services
                .AddCors(o =>
                {
                    o.AddPolicy(PolicyName,
                        b =>
                        {
                            foreach (var origin in originsContainer)
                            {
                                b.WithOrigins(origin)
                                    .WithExposedHeaders(ContentDispositionHeaderName)
                                    .AllowAnyHeader()
                                    .AllowAnyMethod()
                                    .AllowCredentials();
                            }
                        });
                });
        }

添加这一行,解决了问题,文件名可以从这个标题中获得:)


推荐阅读