jquery - Asp.net Core,如何在 JQuery/Ajax 中将文件和模型发布到 Controller ?

标签 jquery asp.net ajax asp.net-mvc controller

此问题与 this 不重复。因为所有细节都在这个问题中得到了充分的描述,非常适合初学者

我有一个继承自模型的 View 。我的字段位于表单中,我想使用 JQuery/Ajax 将表单(或模型)发布到 Controller 并将其插入数据库中。我读过this文章,可以使用 ajax 上传图像,但我无法将带有数据的整个表单或模型发布到 Controller 。

我的观点:

@model ajax1.Models.Info

<form method="post" enctype="multipart/form-data">

<div class="form-group">
    <label asp-for="FirstName" class="col-lg-2 col-sm-2 control-label "></label>
    <div class="col-lg-6">
        <input asp-for="FirstName" class="form-control" />
        <span asp-validation-for="FirstName"></span>
    </div>
</div>

<div class="form-group">
    <label asp-for="LastName" class="col-lg-2 col-sm-2 control-label"></label>
    <div class="col-lg-6">
        <input asp-for="LastName" class="form-control" />
        <span asp-validation-for="LastName"></span>
    </div>
</div>

<input type="file" id="files" name="files" multiple />
<input type="button" id="upload"  value="Upload Selected Files" />
</form>

View 底部的 JQuery 代码:

@section Scripts{
<script>
        $("#upload").click(function (evt) {
            var fileupload = $("#files").get(0);
            var files = fileupload.files;
            var data = new formdata();
            for (var i = 0; i < files.length; i++) {
                data.append(files[i].name, files[i]);
            }
            $.ajax({
                type: "post",
                url: "/home/uploadfilesajax",
                contenttype: false,
                processdata: false,
                data: data,
                success: function (message) {
                    alert(message);
                },
                error: function () {
                    alert("there was error uploading files!");
                }
            });
        });

</script>

}

Controller :

    [HttpPost]
    public async Task<IActionResult> UploadFilesAjax(Info model)
    {
        var files = HttpContext.Request.Form.Files;
        foreach (var Image in files)
        {
            if (Image != null && Image.Length > 0)
            {
                var file = Image;
                var uploads = Path.Combine(_appEnvironment.WebRootPath, "img\\");
                if (file.Length > 0)
                {
                    var fileName = Guid.NewGuid().ToString().Replace("-", "") + Path.GetExtension(file.FileName);
                    using (var fileStream = new FileStream(Path.Combine(uploads, fileName), FileMode.Create))
                    {
                        await file.CopyToAsync(fileStream);
                        model.imgName = fileName;
                    }
                }
            }
        }

        using (var db = _iServiceProvider.GetRequiredService<ApplicationDbContext>())
        {

            db.Info.Add(model);
            db.SaveChanges();
        }
        string message = "success";
        return Json(message);
    }

型号:

public class Info
{
    [DisplayName("First Name")]
    [Required(ErrorMessage = "Enter First Name")]
    public string FirstName { get; set; }

    [DisplayName("Last Name")]
    [Required(ErrorMessage = "Enter Last Name")]
    public string LastName { get; set; }

    [DisplayName("select image")]
    public string imgName { get; set; }
}

当我在操作上设置断点并单击提交按钮时,应用程序不会执行操作。我如何将所有表格或模型发布到 Controller ?我希望如果“ModelStates.IsValid == false”显示验证错误。

最佳答案

您的客户端代码中几乎没有问题。

您使用的 contenttypecontenttypeformdata 大小写不正确。请记住 JavaScript 区分大小写。

您当前的代码仅将图像添加到 FormData 对象。您可以循环遍历输入元素并添加它。

这应该有效。

$(function () {

    $("#upload").click(function (evt) {
        evt.preventDefault();

        var fileupload = $("#files").get(0);
        var files = fileupload.files;
        var data = new FormData();
        for (var i = 0; i < files.length; i++) {
            data.append(files[i].name, files[i]);
        }

        // You can update the jquery selector to use a css class if you want
        $("input[type='text'").each(function (x, y) {
            data.append($(y).attr("name"), $(y).val());
        });

        $.ajax({
            type: "post",
            url: "/home/uploadfilesajax",
            contentType: false,
            processData: false,
            data: data,
            success: function (message) {
                alert(message);
            },
            error: function () {
                alert("there was error uploading files!");
            }
        });
    });  
});

您仍然可以使用模型验证框架来检查 View 模型的属性级别验证。由于您正在进行 ajax 调用,因此需要将 JSON 响应中的验证错误发送回客户端,以便客户端将其显示给用户。

[HttpPost]
public async Task<IActionResult> UploadFilesAjax(Info model, IEnumerable<IFormFile> files)
{
    if (ModelState.IsValid)
    {
        var uploads = Path.Combine(hostingEnvironment.WebRootPath, "images");
        foreach (var file in files)
        {
            if (file != null && file.Length > 0)
            {
                var fileName = Guid.NewGuid().ToString().Replace("-", "") +
                                Path.GetExtension(file.FileName);
                using (var s = new FileStream(Path.Combine(uploads, fileName),
                                                            FileMode.Create))
                {
                    await file.CopyToAsync(s);
                    model.imgName = fileName;
                }
            }
        }
        return Json(new { status = "success", message = "success" });
    }
    else
    {
        var list = new List<string>();
        foreach (var modelStateVal in ViewData.ModelState.Values)
        {
            list.AddRange(modelStateVal.Errors.Select(error => error.ErrorMessage));
        }
        return Json(new { status = "error", errors = list });
    }
}

现在在客户端代码中,读取响应的状态属性,如果有错误,则循环访问错误属性并将其显示给用户。在下面的示例中,我只是向用户发出错误警报,但您可以更改它以将其显示在页面的某些部分。

$(function () {

    $("#upload").click(function (evt) {
        evt.preventDefault();
        var fileupload = $("#files").get(0);
        var files = fileupload.files;
        var data = new FormData();
        for (var i = 0; i < files.length; i++) {
            data.append('files', files[i]);
        }

        // You can update the jquery selector to use a css class if you want
        $("input[type='text'").each(function (x, y) {
            data.append($(y).attr("name"), $(y).val());
        });

        $.ajax({
            type: "post",
            url: "/home/uploadfilesajax",
            contentType: false,
            processData: false,
            data: data
        }).done(function(res) {
            if (res.status === "success") {
                alert(res.message);
            } else {
                $.each(res.errors,function(a, b) {
                        alert(b);
                    });
            }
        }).fail(function(xhr, b, error) {
            alert(error);
        });
    });  
});

关于jquery - Asp.net Core,如何在 JQuery/Ajax 中将文件和模型发布到 Controller ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47233009/

相关文章:

javascript - 使用 XMLHttpRequest 和通用处理程序通过 FTP 下载 PDF 文件

Javascript:从右侧滑动面板

javascript - 如何解决此 WCF/AJAX 问题? (访问数据库时出现 400 Bad Request 错误)

javascript - 在成功函数之外使用通过 AJAX 检索的 JSON 数据

php - 使用日期范围选择器 php 和 ajax 过滤我的数据表

javascript - extjs 4 : display image from Mysql blob value

javascript - 拖放功能匹配图像

jQuery easing plugIn,负scrollTop,到达顶部或底部时

javascript - 如何从 Javascript 中的行获取包含的 WebDataGrid (Infragistics NetAdvantage) 控件?

c# - 在 C# 和 ASP.net 中读取 Cookie; cookie 值滞后