javascript - 通过 mvc 控制器安装 asp.net mvc excel 文件和 asp.net core web api 转发
问题描述
我有 asp.net mvc 和 asp.net core 3.1 amazon s3 项目。我在 asp.net mvc 中加载 excel 文件,这个 excel 文件保存在 amazon s3 中。我使用 asp.net core web api 向 amazon s3 进行了注册。我使用 ajaxForm 进行文件上传。我想尝试的是通过 mvc 控制器将文件上传过程定向到 asp.net core web api。我不能做的另一个问题是在将excel文件保存在amazon s3中后,将文件中包含的数据保存到sql数据库中。我试图从不同的来源寻找结果,但没有成功。我怎样才能做到这一点?
这是我的 MVC 查看代码:
@using (Html.BeginForm("Index", "Admin", FormMethod.Post, new { enctype = "multipart/form-data", id = "Myform" }))
{
<div class="form-group mb-3">
<div class="custom-file">
<input type="file" class="custom-file-input" id="FileUpload" name="FileUpload">
<label class="custom-file-label" for="FileUpload"></label>
</div>
</div>
<button type="submit" id="Submit" class="btn btn-primary"><i class="fa fa-upload" aria-hidden="true"></i> Yükle</button>
<button type="button" id="export" class="btn btn-primary"><i class="fa fa-file-excel-o" aria-hidden="true"></i> Excel'e Aktar</button>
<br /><br />
<ul id="ulList"></ul>
}
这是我的 JavaScript 代码:
$('#Myform').ajaxForm({
beforeSend: function () {
noFiles();
$("#ulList").empty();
$('.progress-bar').width(percentVal);
loader_icon.show();
},
uploadProgress: function (event, position, total, percentComplete) {
var fp = $("#FileUpload");
var lg = fp[0].files.length; // get length
var items = fp[0].files;
var fragment = "";
// disable button
$("#Submit").prop("disabled", true);
// add spinner to button
$("#Submit").html(
`<span style="@@keyframes spinner-border {
to { transform: rotate(360deg); }
}
.spinner-border{
display: inline-block;
width: 2rem;
height: 2rem;
vertical-align: text-bottom;
border: .25em solid currentColor;
border-right-color: transparent;
border-radius: 50%;
-webkit-animation: spinner-border .75s linear infinite;
animation: spinner-border .75s linear infinite;
}
.spinner-border-sm{
height: 1rem;
border-width: .2em;
}" class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Yükleniyor...`
);
if (lg > 0) {
fragment += "<li> Veriler yükleniyor..</li>";
$("#ulList").append(fragment);
for (var i = 0; i < lg; i++) {
var i = 0;
if (i == 0) {
i = 1;
var elem = document.getElementById("myBar");
var width = 0;
var id = setInterval(frame, 100);
function frame() {
if (width >= 100) {
swal({
title: "Başarılı!",
text: "Kayıt Başarılı!",
type: "success",
showCancelButtonClass: "btn-primary",
confirmButtonText: "OK"
});
clearInterval(id);
i = 0;
elem.style.width = "0%";
$("#Submit").prop("disabled", false);
$("#export").prop("disabled", false);
$("#Submit").html("Yükle");
$("#ulList").empty();
var lastFile =$("#onceki").val();
console.log(lastFile);
var prevFile = $("#oncekii").val();
console.log(prevFile);
$.cookie('oncekiYuklenenDosya', lastFile, { expires: 365 });
$.cookie('dahaOncekiYuklenenDosya', prevFile, { expires: 365 });
@*$.ajax({
type: "GET",
url: '@Url.Action("AddMap","Admin")',
success: function (data) {
console.log(data);
},
error: function (error) {
alert(error);
}
});*@
//var myUrl = "myApiUrl";
//var formData = new FormData();
//formData.append("FileUpload", $("#FileUpload").file);
// $.ajax({
// type: "POST",
// url: myUrl,
// data: formData,
// crossDomain: true,
// dataType: 'html',
// contentType: "multipart/form-data",
// headers: {
// //Authorization: "Bearer " + accesstoken,
// 'Access-Control-Allow-Origin': '*'
// },
// success: function (data) {
// alert(data);
// },
// error: function (error) {
// alert(error);
// }
//});
showMap();
} else {
width++;
elem.style.width = width + "%";
elem.innerHTML = width + "%";
}
}
}
}
}
},
complete: function (xhr) {
if (xhr.success == true) {
swal({
title: "Başarılı!",
text: "Kayıt Başarılı!",
type: "success",
showCancelButtonClass: "btn-primary",
confirmButtonText: "OK"
});
}
}
});
这是我要重定向到 web api 的 mvc 控制器:
[HttpPost]
public ActionResult Index(FormCollection formCollection)
{
HttpPostedFileBase file = Request.Files["FileUpload"];
var json = JsonConvert.SerializeObject(
new
{
files = file,
Passed = true,
Mesaj = "item added"
},
new HttpPostedFileConverter());
var stringContent = new StringContent(json, Encoding.UTF8, "multipart/form-data");
try
{
using (var client = new HttpClient())
{
//var userid = Session["UserID"];
client.BaseAddress = new Uri("myApiUrl");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("multipart/form-data"));
//HttpResponseMessage response = await client.PostAsJsonAsync("api/address/postmap?mapList=" + mapList).Result;
HttpResponseMessage response = client.PostAsync("api/address/save?FileUpload=", stringContent).Result;
if (response.IsSuccessStatusCode)
{
return RedirectToAction("Index", "Admin");
}
return null;
}
}
catch (Exception e)
{
ViewBag.Hata = e.Message;
}
return RedirectToAction("Index", "Admin");
}
这是我的 asp.net core 3.1 web api 控制器:
[HttpPost]
[Route("api/address/save")]
public async Task<IActionResult> Save(IFormFile FileUpload)
{
var userId = _httpContextAccessor.HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value;
var uid = Convert.ToInt32(userId);
if (FileUpload.Length == 0)
{
return BadRequest("please provide valid file");
}
var fileName = ContentDispositionHeaderValue
.Parse(FileUpload.ContentDisposition)
.FileName
.TrimStart().ToString();
var folderName = Request.Form.ContainsKey("folder") ? Request.Form["folder"].ToString() : null;
bool status;
using (var fileStream = FileUpload.OpenReadStream())
using (var ms = new MemoryStream())
{
await fileStream.CopyToAsync(ms);
status = await _awsS3Service.UploadFileAsync(ms, fileName, folderName);
var mapList = new List<Map>();
using (var package = new ExcelPackage(ms))
{
ExcelWorksheet worksheet = package.Workbook.Worksheets[0];
var rowCount = worksheet.Dimension.Rows;
for (int row = 2; row <= rowCount; row++)
{
mapList.Add(new Map
{
UserId = uid,
Latitude = worksheet.Cells[row, 1].Value.ToString().Trim(),
Longitude = worksheet.Cells[row, 2].Value.ToString().Trim(),
});
}
}
foreach (var item in mapList)
{
dbContext.Map.Add(item);
}
dbContext.SaveChanges();
}
return status ? Ok("success")
: StatusCode((int)HttpStatusCode.InternalServerError, $"error uploading {fileName}");
}
你认为我在哪里犯了错误?谢谢你。
解决方案
好的,你有几个不同的问题。答案涉及几个不同的部分,包括服务器端(您的 C# ASP.Net Core UI 和 C# .Net Core 控制器)和客户端(您的 ASP.Net Core/Razor 标记和 Javascript)。
另外:我使用术语“ASP.Net Core”来将其与旧的“ASP.Net MVC”区分开来。
让我们分解一下:
MVC View code
(我假设这是一个 ASP.Net Core “页面”):乍一看,看起来不错。javascript code
: 看起来不错。但我不确定你是否需要它...问:你是从你的 MVC 视图代码中调用它吗?如果是这样,怎么做?你能给我们看看吗?如果不是,为什么不呢?
mvc controller I want to redirect to the web api
: 我不确定这是什么,或者你是否需要它。asp.net core 3.1 web api controller
: 看起来不错......但我认为您可以将所有这些功能移至 ASP.Net Core“发布”处理程序。
建议:
- 您的初始“索引”页面处理程序将如下所示:
https://docs.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads?view=aspnetcore-3.1
索引.cshtml:
<form enctype="multipart/form-data" method="post">
<dl>
<dt>
<label asp-for="FileUpload.FormFile"></label>
</dt>
<dd>
<input asp-for="FileUpload.FormFile" type="file">
<span asp-validation-for="FileUpload.FormFile"></span>
</dd>
</dl>
<input asp-page-handler="Upload" class="btn" type="submit" value="Upload" />
</form>
- 您将拥有一个看起来像这样的“Post”处理程序:
https://docs.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads?view=aspnetcore-3.1
index.cshtml.cs:
public async Task<IActionResult> OnPostUploadAsync(List<IFormFile> files)
{
long size = files.Sum(f => f.Length);
foreach (var formFile in files)
{
if (formFile.Length > 0)
{
var filePath = Path.GetTempFileName();
using (var stream = System.IO.File.Create(filePath))
{
await formFile.CopyToAsync(stream);
}
}
}
// Process uploaded files
// Don't rely on or trust the FileName property without validation.
return Ok(new { count = files.Count, size });
}
这将满足您的第一个要求:将文件上传到您的 .Net Core Web 服务器。
如果文件恰好是 Excel 电子表格、.jpg 图像或文本文件,这并不重要——您只是在上传“文件”。
您可以使用适用于 .Net 的 AWS 开发工具包修改“OnPostUploadAsync()”处理程序以将文件发送到 S3 实例:
https://docs.aws.amazon.com/AmazonS3/latest/dev/HLuploadFileDotNet.html
您还可以修改“OnPostUploadAsync()”以将文件写入 SQL 数据库:
https://www.c-sharpcorner.com/article/upload-files-in-azure-blob-storage-using-asp-net-core/
如果您希望能够在运行时选择“将文件保存到服务器”、“将文件上传到 S3”或“将文件写入 MSSQL”,那么
- 将单选按钮或复选框添加到您的 Index.cshtml 标记
- 读取值并从“OnPostUploadAsync()”处理程序中调用适当的方法。
https://en.wikipedia.org/wiki/ASP.NET_MVC
ASP.NET MVC 是由 Microsoft 开发的已停止使用的 Web 应用程序框架,它实现了模型-视图-控制器 (MVC) 模式。它是开源软件,除了专有的 ASP.NET Web 窗体组件。
ASP.NET Core 已经发布,它统一了 ASP.NET、ASP.NET MVC、ASP.NET Web API 和 ASP.NET Web Pages(一个只使用 Razor 页面的平台)。MVC 6 因 Core 而被放弃,预计不会发布。Core 目前计划合并到.NET 5中。
请记住 - .Net Core(无论是 ASP.Net Core “页面”还是 .Net Core “控制器”)只是HTTP 请求和响应之上的一个抽象层。最终,这一切都只是 HTTP GET 和 POST。 不是“控制器”,不是“页面”。
是的,您可以将 POST 请求处理程序放入“控制器”(而不是 ASP.Net Core“页面”)。您所要做的就是 1) 编写一个新的控制器模块,2) 使用我在上面发布的相同代码,3) 确保定义到控制器的路由,以及 4)<form>
使用该 URL 而不是默认 URL。
十分简单。
但我敦促你以我的方式尝试。
让它工作。
然后,一旦它开始工作......一旦你更好地了解它是如何工作的,然后扩展你的解决方案。
朝着您的解决方案迈出“小步”。这是一篇关于这个主题的好文章:
https://blog.adrianbolboaca.ro/2013/01/the-history-of-taking-baby-steps/
不要气馁。
祝你好运。
推荐阅读
- javascript - Javascript,HTML:设置网页移动到 about:blank 页面并禁用返回(杀死页面)
- reactjs - 不推荐使用 btoa 时如何在 ReactJS 中编码 base 64 字符串?
- powershell - 远程访问 DC 安全事件完整数据
- angular - 来自对象数组的角度显示表数据,但从另一个 API 调用更新最后一列返回未定义的值
- reactjs - 无法从 VS Code 运行 Android 模拟器
- zsh - 是否可以在 TIG 中直接从键绑定中搜索特定字符串?
- python - 如何使用唯一索引索引列表中的每个元素
- django - Django - 如何通过唯一的父字段值对 forms.CheckboxSelectMultiple 项目进行分组?
- python - 如何在两个日期之间的对象列表中搜索值python
- arrays - go语言中如何将带有map的struct存储到数组中