簡體   English   中英

無法使用 C# 客戶端將 IFormFile 發送到 ASP.Net Core Web API

[英]unable to send IFormFile to ASP.Net Core Web API using C# client

我有一個 ASP.Net Core Web API,控制器 POST 方法定義如下:

[HttpPost("SubmitFile")]
public async Task<IActionResult> SubmitFile(IFormFile file)
{
}

我有一個客戶端方法來調用 API SubmitFile() 方法,定義如下:

[HttpPost]
public async Task<IActionResult> Index(ICollection<IFormFile> files)
{
     using (var client = new HttpClient())
     {
         client.BaseAddress = new Uri(_options.SiteSpecificUrl);

         foreach (var file in files)
         {
             if (file.Length <= 0)
                 continue;

             var fileName = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');
             var fileContent = new StreamContent(file.OpenReadStream());
             fileContent.Headers.Add("X-FileName", fileName);
             fileContent.Headers.Add("X-ContentType", file.ContentType);

             var response = await client.PostAsync(_options.WebApiPortionOfUrl, fileContent);
         }
     }

    return View();
}

當執行客戶端發送時,在服務器端,SubmitFile() 中的斷點顯示文件參數為空。 如何正確發送文件? 保留服務器端 API 很重要,因為我讓 Swashbuckle/Swagger 正確生成可以發送文件的 UI。

我找到了幾種方法來做到這一點。 這里是最簡單的。 請注意,這是一個 ASP.Net Core 客戶端解決方案:

[HttpPost]
public async Task<IActionResult> Index(ICollection<IFormFile> files)
{
    using (var client = new HttpClient())
    {
        client.BaseAddress = new Uri(_options.SiteSpecificUrl);

        foreach (var file in files)
        {
            if (file.Length <= 0)
                continue;

            var fileName = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');

            using (var content = new MultipartFormDataContent())
            {
                content.Add(new StreamContent(file.OpenReadStream())
                {
                    Headers =
                    {
                        ContentLength = file.Length,
                        ContentType = new MediaTypeHeaderValue(file.ContentType)
                    }
                }, "File", fileName);

                var response = await client.PostAsync(_options.WebApiPortionOfUrl, content);
            }
        }
    }
}

這個控制器方法是從 .cshtml 頁面調用的,如下所示:

@{
    ViewData["Title"] = "Home Page";
}

<form method="post" asp-action="Index" asp-controller="Home" enctype="multipart/form-data">
    <input type="file" name="files" multiple />
    <input type="submit" value="Upload" />
</form>

此窗體顯示兩個按鈕,“選擇文件”,它顯示一個“選擇文件”對話框,以及“上傳”,它調用 HomeController.Index 方法。

這對我有用:

前端:

HTML/CSS:

<div id="" class="col-xs-12 info-box">
<div class="col-xs-12">  
    <a role="button" data-toggle="collapse" href="#upload-sample" aria-expanded="false"> 
        <h3><span class="glyphicon glyphicon-upload"></span> Upload de Arquivo</h3>
    </a>
</div>   
<div id="upload-sample" class="col-xs-12 collapse">  
    <form method="post" enctype="multipart/form-data">
        <div>
            <div class="form-group attach" style="width: 100%;">
                <label>Select Excel File <button type="button" id="btnDownloadTemplate">(Download Template)</button></label>
                <div class="col-md-12"><input type="file" id="fUpload" name="files" multiple class="form-control" style="max-width: 400px;" /></div>
            </div>                
            <div class="filter-button" style="width: 100%;">                     
                <button onclick="AJAXSubmit(this); return false;" id="btnUpload" class="btn btn-primary">Send File and update data</button>
            </div>
        </div>
    </form>
</div>      

JavaScript:

async function AJAXSubmit(oFormElement) {
    const files = $('#fUpload').prop("files");
    const fdata = new FormData();
    for (var i = 0; i < files.length; i++) {
        fdata.append("files", files[i]);
    }
    if (files.length > 0) {
        Block();
        $.ajax({
            type: "POST",
            url: "/{{controllerName}}/OnPostUpload?handler=Upload",
            beforeSend: function (xhr) {
                xhr.setRequestHeader("XSRF-TOKEN",
                    $('input:hidden[name="__RequestVerificationToken"]').val());
            },
            data: fdata,
            contentType: false,
            processData: false,
            success: function (response) {
                document.getElementById("fUpload").value = "";
                //Unblock();                    
                //toastr.success(response, "File processed successfully");
                FilterHandlebarsF.Search(this, true);
            },
            error: function (response) {                    
                document.getElementById("fUpload").value = "";
                //Unblock();
                //toastr.warning(response, "Error on processing");
            }
        });
    }
    else {
        //toastr.warning("Please, select a file.");
    }
}

后端:

Startup.cs: services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");

控制器:

public ActionResult OnPostUpload(List<IFormFile> files)
    {
        try
        {
            var file = files.FirstOrDefault();
            var inputstream = file.OpenReadStream();

            XSSFWorkbook workbook = new XSSFWorkbook(stream);

            var FIRST_ROW_NUMBER = {{firstRowWithValue}};

            ISheet sheet = workbook.GetSheetAt(0);
            // Example: var firstCellRow = (int)sheet.GetRow(0).GetCell(0).NumericCellValue;

            for (int rowIdx = 2; rowIdx <= sheet.LastRowNum; rowIdx++)
               {
                  IRow currentRow = sheet.GetRow(rowIdx);

                  if (currentRow == null || currentRow.Cells == null || currentRow.Cells.Count() < FIRST_ROW_NUMBER) break;

                  var df = new DataFormatter();                

                  for (int cellNumber = {{firstCellWithValue}}; cellNumber < {{lastCellWithValue}}; cellNumber++)
                      {
                         //business logic & saving data to DB                        
                      }               
                 }
        }
        catch(Exception ex)
        {
            throw new FileFormatException($"Error on file processing - {ex.Message}");
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM