2021年1月11日 星期一

在 .Net Core 3 上使用 IHttpClient 取得圖片並下載到本地端

因為某些因素需透過圖片連結位址取得目標圖片之 Stream 格式並供網站系統利用,聽起來不是太難的功能,所以照慣例,先詢問谷狗大神參考一下大家的做法,看到蠻多都是採建立 HttpClient 的物件並呼叫 GetStreamAsync() 方法來直接取得。但不知道什麼原因,自己試過後,發現這方法對我行不通,只能透過 GetByteArrayAsync() 方式才能成功取到圖片資源,因此稍微修正了一下實做方式並在這邊做個記錄。


1. 需先在 Startup.cs 檔案裡的 ConfigureServices 方法中加入 services.AddHttpClient();

public class Startup
{
    public IConfiguration _configuration { get; }

    public Startup(IConfiguration configuration)
    {
        _configuration = configuration;
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddHttpClient();
        // Remaining code deleted for brevity.
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        // Remaining code deleted for brevity.
    }  
}  

2. 然後在 Controller 中透過 DI 注入 IHttpClientFactory,並透過它取得圖檔。詳細部分如下:

public class CrawlerController : Controller
{
    private readonly IHttpClientFactory _httpClientFactory;
    public CrawlerController(IHttpClientFactory httpClientFactory)
    {
        _httpClientFactory = httpClientFactory;
    }

    [HttpGet]
    public async Task<ActionResult> Get()
    {
        // 1. 建立 HttpClient 物件
        var client = _httpClientFactory.CreateClient();
        var imageUrl = "https://raw.githubusercontent.com/linmasaki/SlimeRacing/master/demo_1.jpg";
        var filename = new Uri(imageUrl).Segments.Last();

        // 2. 不用 GetStreamAsync(),而是使用 GetByteArrayAsync() 方式取得圖片二進位檔,然後才再轉成 Stream 格式
        using (var memoryStream = new MemoryStream(await client.GetByteArrayAsync(imageUrl)))
        {
            // 3. 使用 memoryStream 實做你的商業邏輯,e.g. 例如存到本地 C 磁碟的 temp 路徑下
            using (var output = new FileStream($"C:/temp/{filename}", FileMode.Create))
            {
                await memoryStream.CopyToAsync(output).ConfigureAwait(false);
            }
        }
    }
}




參考資料

[Microsoft] Make HTTP requests using IHttpClientFactory in ASP.NET Core

[精緻碼農] NET Core 中正确使用 HttpClient 的姿势

訪客統計

103197