【问题标题】:Installing asp.net mvc excel file and asp.net core web api forwarding via mvc controller通过 mvc 控制器安装 asp.net mvc excel 文件和 asp.net core web api 转发
【发布时间】:2020-10-31 14:53:22
【问题描述】:

我有 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}");
    }

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

【问题讨论】:

  • 您将许多不同的东西混合在一起。您的主要问题究竟是什么?
  • 你说的很对,我的主要问题是无法将文件从控制器发送到 web api。
  • 我的第二个问题是在web api中加载excel文件后无法将excel中的数据保存到sql数据库中。当我尝试使用 Postman 时,我收到 500 间隔错误错误。当我尝试使用 mvc 时,出现 400 错误。
  • 问:您是否尝试过我的建议:在一个页面中使用两个处理程序(GET 和 POST)请求文件并下载到服务器?它奏效了吗?主要的事情(如我所见)是让 SOMETHING 快速工作;以后你总是可以改变和解释事情。
  • 您好,我尝试了您的建议,但没有成功。我需要将选定的excel文件作为参数发送到web api,但是我无法执行此操作。

标签: javascript .net asp.net-core amazon-s3


【解决方案1】:

好的,您有几个不同的问题。答案涉及几个不同的部分,包括服务器端(您的 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

index.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 是已停止开发的 Web 应用程序框架 微软,它实现了模型-视图-控制器(MVC) 图案。它是开源软件,除了 ASP.NET Web 表单 专有组件。

ASP.NET Core 已经发布,它统一了 ASP.NET、ASP.NET MVC、ASP.NET Web API 和 ASP.NET 网页(仅使用 剃刀页面)。 MVC 6 因 Core 而被放弃,预计不会 被发布。 Core 目前计划合并到.NET 5

请记住 - .Net Core(无论是 ASP.Net Core “页面”还是 .Net Core “控制器”)只是 HTTP 请求和响应之上的 abstraction layer。最终,这一切都只是 HTTP GET 和 POST。 不是“控制器”,而不是“页面”。

是的,您可以将您的 POST 请求处理程序放入“控制器”(而不是 ASP.Net Core“页面”)。您所要做的就是 1) 编写一个新的控制器模块,2) 使用我在上面发布的 SAME 代码,3) 确保为控制器定义 route,以及 4) 使您的&lt;form&gt; 使用该网址而不是默认网址。

简单易懂。

但我强烈建议你按照我的方式尝试。

让它工作。

然后,一旦它开始工作......并且一旦你更好地理解它如何工作,然后扩展你的解决方案。

朝着您的解决方案迈出“小步”。这是一篇关于这个主题的好文章:

https://blog.adrianbolboaca.ro/2013/01/the-history-of-taking-baby-steps/

不要气馁。

祝你好运。

【讨论】:

  • 首先,感谢您的回复。我为“index.cshtml”做了你的指示。但是如何将我在asp.net mvc中选择的文件重定向到asp.net core web api“OnPostUploadAsync”方法?
  • 您不会“重定向文件” - 没有这样的事情。具体来说,all 您需要做的是 1) 在您的 .cshtml 中使用 &lt;form ... method="post"&gt;,以及 2) 在您的 .cshtml.cs 中使用 public async Task&lt;IActionResult&gt; OnPostUploadAsync(List&lt;IFormFile&gt; files) 处理程序。您最初的方法“过于复杂”:您真的不需要所有这些东西。如果您觉得回复有用,请“点赞”和“接受”。
  • 由于这个项目会在服务器上,所以每个进程都必须来自api。所以我必须将mvc中的文件发送到api。我在从控制器传输到 api 时遇到问题。
  • 我告诉你:KEEP IT SIMPLE。请尝试我的建议。你可以随时改变……以后。一定要在 MSVS 调试器和/或 Chrome 开发者工具中单步调试你的代码,这样你就确定你明白发生了什么。请试一试,然后发回你发现的内容。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-16
  • 2023-03-11
  • 2012-09-04
  • 2016-05-20
相关资源
最近更新 更多