使用ajax发布视图模型,其中包含MVC Core中的IFormFile属性 [英] Using ajax to post a view model which includes an IFormFile property in MVC Core

查看:257
本文介绍了使用ajax发布视图模型,其中包含MVC Core中的IFormFile属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用jquery AJAX帖子在MVC核心中发布一个简单的viewmodel,但IFormFile属性似乎在模型上为null。

I'm trying to post a simple viewmodel in MVC core using a jquery AJAX post, however the IFormFile property seems to be null on the model.

我有以下视图模型:

    [Required]
    public IFormFile File { get; set; }

    [Required]
    [Display(Name = "Owner")]
    public int DocumentOwner { get; set; }

    [Required]
    [Display(Name = "Document Type")]
    public int DocumentTypeId { get; set; }

然后我在视图底部的脚本中使用jQuery ajax帖子:

I then use a jQuery ajax post inside a script at the bottom of my view:

$("form").submit(function (e) {
    e.preventDefault();

    var model = $('form').serialize();

    $.ajax({
        type: "POST",
        url: "/Client/AddDocument",
        contentType: false,
        processData: false,
        data: model,
        success: function (message) {
            alert(message);
        },
        error: function () {
            alert("There was error uploading files!");
        }
    });
});

viewmodel成功将其他值传递给控制器​​,但文件以null结尾。

The viewmodel is successfully passing the other values to the controller, however the file is coming through as null.

任何人都可以提供帮助吗?

Anyone able to help?

推荐答案

不幸的是jQuery serialize()方法不包含输入文件元素。所以选择的文件用户不会包含在序列化值中。

Unfortunately the jQuery serialize() method will not include input file elements. So file user selected is not going to be included in the serialized value.

你可能会做的是,创建一个 FormData object,将文件附加到该文件。您还需要将表单字段值附加到此相同的 FormData 对象。您可以简单地遍历所有输入字段并添加它。此外,在ajax调用中,您需要将 processData contentType 属性值指定为 false

What you may do is, create a FormData object, append the files to that. You need to append the form field values as well to this same FormData object. You may simply loop through all the input field and add it. Also, in the ajax call, you need to specify processData and contentType property values to false

这应该有效

$(function () {

    $("form").submit(function (e) {
        e.preventDefault();

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

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

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

        $.ajax({
            type: 'post',
            url: formAction ,
            data: fdata,
            processData: false,
            contentType: false
        }).done(function(result) {
            // do something with the result now
            console.log(result);
        });

    });

 });

以上代码正在从表单(已提交)中读取action属性并将其用作ajax表单提交的URL。

The above code is reading the action attribute from the form ( which was submitted) and using that as the url for the ajax form submit.

@model YourViewModel
<form asp-action="Index" asp-controller="Home" method="post" >

    <label asp-for="DocumentOwner"></label>
    <input type="text" asp-for="DocumentOwner" />

    <label asp-for="DocumentTypeId"></label>
    <input type="text" asp-for="DocumentTypeId" />

    <label asp-for="File"></label>
    <input asp-for="File" />

    <input type="submit"  />
</form>

在您的HttpPost操作方法中,您可以使用与参数相同的视图模型。下面的示例代码读取文件属性并将其保存到 wwwroot中的 uploads 目录中目录。

In your HttpPost action method, you can use the same view model as the parameter. The below sample code read the File property and save it to the uploads directory inside the wwwroot directory.

public class HomeController : Controller
{
    private readonly IHostingEnvironment hostingEnvironment;
    public HomeController(IHostingEnvironment environment)
    {
        hostingEnvironment = environment;
    }
    [HttpPost]
    public IActionResult Index(YourViewModel vm)
    {
        if (ModelState.IsValid)
        {
            if (vm.File != null)
            {
                var uploads = Path.Combine(hostingEnvironment.WebRootPath, "uploads");
                var filePath = Path.Combine(uploads, GetUniqueFileName(vm.File.FileName));
                vm.File.CopyTo(new FileStream(filePath, FileMode.Create));
                return Json(new {status = "success", message = "Successfully saved"});
            }
        }
        else
        {
            // handle what to do when model validation fails
        }
        return Json(new {status = "error", message = "something wrong!"});
    }
    private string GetUniqueFileName(string fileName)
    {
        fileName = Path.GetFileName(fileName);
        return  Path.GetFileNameWithoutExtension(fileName)
                  + "_" + Guid.NewGuid().ToString().Substring(0, 4) 
                  + Path.GetExtension(fileName);
    }
}

这篇关于使用ajax发布视图模型,其中包含MVC Core中的IFormFile属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆