在 ASP.Net Core MVC 中使用 AJAX 提交表单

新手上路,请多包涵

我正在使用 ASP.Net Core 2.1,并尝试在不刷新页面的情况下上传文件,同时返回它的 url。

我正在尝试在 site.js 中编写 JavaScript,因为 _RenderPartial(“scripts”) 在页面末尾呈现所有脚本,因此直接在 razor 视图中使用脚本标签是行不通的。其次,将它添加到 site.js 让我有机会跨站点视图调用脚本。

我的控制器动作看起来像:

     [HttpPost]
    [DisableRequestSizeLimit]
    public async Task<IActionResult> Upload()
    {
      // Read & copy to stream the content of MultiPart-Form
      // Return the URL of the uploaded file
      return Content(FileName);
    }

我的观点看起来像:

 <form id="FileUploadForm" action="~/Resources/Upload" method="post" enctype="multipart/form-data">
<input name="uploadfile" type="file" />
<button name="uploadbtn" type="submit" onclick="SubmitForm(this.parentElement, event)">Upload</button>

site.js 目前看起来像:

 function SubmitForm(form, caller) {
caller.preventDefault();
$.ajax(
    {
        type: form.method,
        url: form.action,
        data: form.serialize(),
        success: function (data) { alert(data); },
        error: function (data) { alert(data); }
    })}

目前,代码绕过整个脚本并上传文件并返回显示文件名的新视图。我需要帮助来创建 javascript。

原文由 Praveen Rai 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 798
2 个回答

不幸的是,jQuery serialize() 方法将不包含输入文件元素。因此,用户选择的文件不会包含在序列化值(基本上是一个字符串)中。

您可以做的是,创建一个 FormData 对象,将文件附加到该对象。进行ajax调用时,您需要将 processDatacontentType 属性值指定为 false

 <form id="FileUploadForm" asp-action="Upload" asp-controller="Home"
                                              method="post" enctype="multipart/form-data">
    <input id="uploadfile" type="file" />
    <button name="uploadbtn" type="submit">Upload</button>
</form>

在这里以不显眼的方式处理表单提交事件,我们将停止常规行为并改为执行 ajax 提交。

 $(function () {
    $("#FileUploadForm").submit(function (e) {
        e.preventDefault();

        console.log('Doing ajax submit');

        var formAction = $(this).attr("action");
        var fdata = new FormData();

        var fileInput = $('#uploadfile')[0];
        var file = fileInput.files[0];
        fdata.append("file", file);

        $.ajax({
            type: 'post',
            url: formAction,
            data: fdata,
            processData: false,
            contentType: false
        }).done(function (result) {
            // do something with the result now
            console.log(result);
            if (result.status === "success") {
                alert(result.url);
            } else {
                alert(result.message);
            }
        });
    });
})

假设您的服务器端方法的参数名称与我们在创建 FormData 对象条目时使用的名称相同( file )。这是一个示例,它将图像上传到 uploads 目录中的 wwwwroot

操作方法返回一个具有状态和 url/消息属性的 JSON 对象,您可以在 success / done ajax 调用处理程序中使用它来执行任何操作。

 public class HomeController : Controller
{
    private readonly IHostingEnvironment hostingEnvironment;
    public HomeController(IHostingEnvironment environment)
    {
        _context = context;
        hostingEnvironment = environment;
    }
    [HttpPost]
    public async Task<IActionResult> Upload(IFormFile file)
    {
        try
        {
            var uniqueFileName = GetUniqueFileName(file.FileName);
            var uploads = Path.Combine(hostingEnvironment.WebRootPath, "uploads");
            var filePath = Path.Combine(uploads, uniqueFileName);
            file.CopyTo(new FileStream(filePath, FileMode.Create));
            var url = Url.Content("~/uploads/" + uniqueFileName);
            return Json(new { status = "success", url = url });
        }
        catch(Exception ex)
        {
            // to do : log error
            return Json(new { status = "error", message = ex.Message });
        }
    }
    private string GetUniqueFileName(string fileName)
    {
        fileName = Path.GetFileName(fileName);
        return Path.GetFileNameWithoutExtension(fileName)
                  + "_"
                  + Guid.NewGuid().ToString().Substring(0, 4)
                  + Path.GetExtension(fileName);
    }
}

原文由 Shyju 发布,翻译遵循 CC BY-SA 4.0 许可协议

分享对我有用的代码,实现@Shyju 的回答。

查看(剃刀页面):

 <form name="UploadForm" action="~/Resources/Upload" method="post" enctype="multipart/form-data">
<input name="uploadfile" type="file" />
<button name="uploadbtn" type="submit" onclick="SubmitForm(this.parentElement, event)">Upload</button>

在 Site.js 中添加的 AJAX 代码(使其可重用):

 // The function takes Form and the event object as parameter
function SubmitForm(frm, caller) {
caller.preventDefault();

var fdata = new FormData();

var file = $(frm).find('input:file[name="uploadfile"]')[0].files[0];
fdata.append("file", file);

$.ajax(
    {
        type: frm.method,
        url: frm.action,
        data: fdata,
        processData: false,
        contentType: false,
        success: function (data) {
            alert(data);
        },
        error: function (data) {
            alert(data);
        }
    })

};

原文由 Praveen Rai 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题