如何用C#和JavaScript向Controller传递XLSX与HTML文件?
解决XLSX和HTML文件上传到ASP.NET Core Controller的问题
核心问题说明
当前代码无法正确传递文件的原因:
- 直接获取
input[type=file].value只能得到文件名,而非文件内容 - JSON格式无法传输二进制文件,必须用
multipart/form-data编码 - Model中用
string类型无法接收文件内容,ASP.NET Core上传文件需用IFormFile类型
1. 修改ViewModel(Model)
将文件属性改为IFormFile类型,需引用Microsoft.AspNetCore.Http命名空间:
using Microsoft.AspNetCore.Http; public class DisparoEmailViewModel { public string Titulo { get; set; } public IFormFile Corpo { get; set; } // 对应HTML文件 public IFormFile Parametros { get; set; } // 对应XLSX文件 public List<Parametro1> Parametro1s { get; set; } public List<Parametro2> Parametro2s { get; set; } }
2. 修改HTML代码
- 给文件输入框添加
name属性,值需与ViewModel的属性名一致 - 可添加
accept属性限制文件类型,避免用户选错文件 - 统一按钮点击事件名称:
<div class="flex flex-column"> <!--Para inserir o titulo do email--> <h6>Titulo:</h6> <input id="titulo" name="Titulo" type="text" placeholder="Titulo do Email" style="margin: 0 !important; width: 280px;" /> </div> <div class="flex flex-column"> <!--Para inserir o corpo do email--> <h6>Anexar corpo do email:</h6> <input type="file" id="corpo" name="Corpo" accept=".html" /> </div> <div class="flex flex-column"> <!--Para parametro e os emails--> <h6>Importar planilha de e-mails:</h6> <input type="file" id="parametros" name="Parametros" accept=".xlsx" /> </div> </div> <div class="button-space"> <input class="btn btn-primary" type="button" value="Preparar e-mails" onclick="EnviarEmail()" /> </div>
3. 修改JavaScript代码
使用FormData构建表单数据,替代JSON格式传输文件:
function EnviarEmail() { const formData = new FormData(); // 添加文本字段 formData.append('Titulo', document.getElementById("titulo").value); // 添加HTML文件 const corpoFile = document.getElementById("corpo").files[0]; if (corpoFile) { formData.append('Corpo', corpoFile); } // 添加XLSX文件 const parametrosFile = document.getElementById("parametros").files[0]; if (parametrosFile) { formData.append('Parametros', parametrosFile); } // POST请求 fetch('/DisparoEmail/EnviaEmail', { method: 'POST', body: formData // 无需手动设置Content-Type,浏览器自动处理编码 }) .then((response) => response.arrayBuffer()) .then((buffer) => { const decoder = new TextDecoder('iso-8859-1'); const text = decoder.decode(buffer); // document.querySelector("#divListaFila").innerHTML = text; }) .catch((error) => { console.error('Error:', error); }); }
4. 修改Controller代码
添加[FromForm]特性确保表单数据绑定,优化返回类型与参数校验:
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Http; public class DisparoEmailController : Controller { [HttpPost] public IActionResult EnviaEmail([FromForm] DisparoEmailViewModel email) { if (email == null || !ModelState.IsValid) { return BadRequest("Dados inválidos"); } // 读取HTML文件内容示例 if (email.Corpo != null && email.Corpo.Length > 0) { using var reader = new StreamReader(email.Corpo.OpenReadStream()); string htmlContent = reader.ReadToEnd(); // 后续处理逻辑 } // 读取XLSX文件内容示例(需引入EPPlus等处理库) if (email.Parametros != null && email.Parametros.Length > 0) { // using var package = new ExcelPackage(email.Parametros.OpenReadStream()); // 后续处理逻辑 } DisparoEmailExtension teste = new DisparoEmailExtension(); teste.EnviaEmail(email); return Ok(true); } }
关键注意事项
IFormFile是ASP.NET Core专门用于接收上传文件的类型,可获取文件名、大小、文件流等信息- 上传文件必须使用
multipart/form-data编码,手动构建FormData时无需设置Content-Type,浏览器会自动添加正确的边界标识 - 文件输入框的
name属性必须与ViewModel的属性名完全一致,否则无法完成模型绑定
内容的提问来源于stack exchange,提问作者josé djalma
相关产品推荐
相关产品推荐

