代码之家  ›  专栏  ›  技术社区  ›  Praveen Rai

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

  •  2
  • Praveen Rai  · 技术社区  · 7 年前

    我正在使用ASP.Net Core 2.1,并试图上传一个文件,同时返回它的url,而不刷新页面。

    我试图在site.js中编写JavaScript,因为_RenderPartial(“脚本”)在页面末尾呈现所有脚本,因此直接在razor视图中使用script标记不起作用。其次,将它添加到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。

    2 回复  |  直到 7 年前
        1
  •  5
  •   Shyju    7 年前

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

    你可以做的是,创建一个 FormData 对象,将文件附加到该对象。当制作 ajax调用,需要指定 processData contentType 属性值到 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);
                }
            });
        });
    })
    

    假设您的服务器端方法的参数名与我们创建 表格数据 对象项( file ). 这是一个将图像上传到 uploads 内部目录 wwwwroot .

    action方法返回一个带有status和url/message属性的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);
        }
    }
    
        2
  •  0
  •   Praveen Rai    7 年前

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

    视图(Razor页面):

    <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);
            }
        })
    

    };

    推荐文章