首页 > 解决方案 > 通过 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}");
    }

你认为我在哪里犯了错误?谢谢你。

标签: javascript.netasp.net-coreamazon-s3

解决方案


好的,你有几个不同的问题。答案涉及几个不同的部分,包括服务器端(您的 C# ASP.Net Core UI 和 C# .Net Core 控制器)和客户端(您的 ASP.Net Core/Razor 标记和 Javascript)。

另外:我使用术语“ASP.Net Core”来将其与旧的“ASP.Net MVC”区分开来。

让我们分解一下:

  1. MVC View code(我假设这是一个 ASP.Net Core “页面”):乍一看,看起来不错。

  2. javascript code: 看起来不错。但我不确定你是否需要它...

    问:你是从你的 MVC 视图代码中调用它吗?如果是这样,怎么做?你能给我们看看吗?如果不是,为什么不呢?

  3. mvc controller I want to redirect to the web api: 我不确定这是什么,或者你是否需要它。

  4. asp.net core 3.1 web api controller: 看起来不错...

    ...但我认为您可以将所有这些功能移至 ASP.Net Core“发布”处理程序。

建议:

  1. 您的初始“索引”页面处理程序将如下所示:

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>
  1. 您将拥有一个看起来像这样的“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 });
}
  1. 这将满足您的第一个要求:将文件上传到您的 .Net Core Web 服务器。

  2. 如果文件恰好是 Excel 电子表格、.jpg 图像或文本文件,这并不重要——您只是在上传“文件”。

  3. 您可以使用适用于 .Net 的 AWS 开发工具包修改“OnPostUploadAsync()”处理程序以将文件发送到 S3 实例:

    https://docs.aws.amazon.com/AmazonS3/latest/dev/HLuploadFileDotNet.html

  4. 您还可以修改“OnPostUploadAsync()”以将文件写入 SQL 数据库:

    https://www.c-sharpcorner.com/article/upload-files-in-azure-blob-storage-using-asp-net-core/

  5. 如果您希望能够在运行时选择“将文件保存到服务器”、“将文件上传到 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/

不要气馁。

祝你好运。


推荐阅读