在ASP.NET Core MVC6中将文件和模型发布到控制器 [英] Posting files and model to controller in ASP.NET Core MVC6

查看:86
本文介绍了在ASP.NET Core MVC6中将文件和模型发布到控制器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将一个项目从ASP.NET RC1迁移到ASP.NET Core 1.0.

I'm migrating a project from ASP.NET RC1 to ASP.NET Core 1.0.

我有一个视图,该视图允许用户上传多个文件之一,这些文件是我使用Jquery Ajax发布的.我还序列化并在同一帖子中发布了一些设置.

I have a view that allows users to upload one of more files, which I post using Jquery Ajax. I also serialize and post some settings within the same post.

以下所有内容均在RC1(和pre-asp.net核心)中工作:

The following all worked in RC1 (and pre-asp.net core):

Js:

    $('#submit').click(function () {      
        var postData = $('#fields :input').serializeArray();
        var fileSelect = document.getElementById('file-select');
        var files = fileSelect.files;

        var data = new FormData();
        for (var i = 0; i < files.length; i++) {
            data.append('file' + i, files[i]);
        }
        $.each(postData, function (key, input) {
            data.append(input.name, input.value);
        });
        var url = '/ajax/uploadfile';
        $.ajax({
            url: url,
            type: "POST",
            contentType: false,
            processData: false,
            cache: false,
            data: data,
            success: function (result) {
                alert('success');                   
            },
            error: function () {
                alert('error'); 
            }
        });
    });

控制器:

  public IActionResult UploadFile(UploadFileModel model)
    {
        var result = new JsonResultData();
        try
        {
            if (Request.Form.Files.Count > 0)
            {
                IFormFile file = Request.Form.Files[0];
                //etc
             }
        }
     }

因此,以上操作不再起作用,没有文件上传,也没有模型绑定. 我设法解决了一半的问题,因此现在我可以使模型与以下代码绑定.但是,控制器仍会在Request.Files上给我一个例外.我添加了标头"属性,并使用了serializeObject(自定义方法).在控制器中,我添加了FromBody.

So the above does not work anymore, no file uploaded and no model bound. I managed to fix half the issues so now I can get the model to bind with the following code. However, the controller will still give me an exception on the Request.Files. I added the 'headers' property, and I used serializeObject (custom method). In the controller I added FromBody.

Js:

 $('#submit').click(function () {      
        var postData = $('#fields :input').serializeArray();
        var fileSelect = document.getElementById('file-select');
        var files = fileSelect.files;

        var data = new FormData();
        for (var i = 0; i < files.length; i++) {
            data.append('file' + i, files[i]);
        }
        $.each(postData, function (key, input) {
            data.append(input.name, input.value);
        });
        var url = '/ajax/uploadfile';
        $.ajax({
            url: url,
            type: "POST",
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json'
            },
            processData: false,
            cache: false,
            data: serializeAndStingifyArray(data),
            success: function (result) {
                alert('success');                   
            },
            error: function () {
                alert('error'); 
            }
        });
    });

    function serializeAndStingifyArray(array) {
    var o = {};
    var a = array;
    $.each(a, function () {
        if (o[this.name] !== undefined) {
            if (!o[this.name].push) {
                o[this.name] = [o[this.name]];
            }
            o[this.name].push(this.value || '');
        } else {
            o[this.name] = this.value || '';
        }
    });
    return JSON.stringify(o);
};

控制器:

    [HttpPost]
    public IActionResult UploadFile([FromBody]UploadFileModel model)
    {
        var result = new JsonResultData();
        try
        {
            if (Request.Form.Files.Count > 0)
            {
                IFormFile file = Request.Form.Files[0];
                //etc
             }
         }
       }

html:

    <div id="file-list">
    <input type="file" name="file" class="file-select" accept="application/pdf,application">
    <input type="file" name="file" class="file-select"           accept="application/pdf,application" />
    </div>

推荐答案

我从本文开始,其代码与您的代码几乎相同.

I started from this article which has some code that is almost the same as yours Upload Files In ASP.NET Core 1.0 (see Ajax case).

这对我来说在1.0.0上很好,所以我实现了您的更改,我看到的是它未能在请求中发送文件(客户端问题).

That worked for me fine on 1.0.0, so I implemented your changes and what I saw is that it failed to send the files in the request (client side issue).

这是在chrome中使用F12正常工作时有效负载的外观:(不确定为什么chrome隐藏了文件内容).

This is how the payload should look like when working ok using F12 in chrome: (not sure why the file contents are hidden by chrome).

进行一些调试,您将错误的数据传递给data.append

A little debugging and you are passing wrong data to data.append

解决方法在此行

        $(".file-select").each(function () { data.append($(this).val(), $(this).get(0).files[0]); i++; })

完整代码:

$(document).ready(function () {
    $("#submit").click(function (evt) {

        var data = new FormData();
        i = 0;

        $(".file-select").each(function () { data.append($(this).val(), $(this).get(0).files[0]); i++; })

        var postData = $('#fields :input');
        $.each(postData, function (key, input) {
            data.append(input.name, input.value);
        });

        $.ajax({
            type: "POST",
            url: "/ajax/uploadfile",     // <--- Double check this url.
            contentType: false,
            processData: false,
            data: data,
            success: function (message) {
                alert(message);
            },
            error: function () {
                alert("There was error uploading files!");
            }
        });
    });
});

无需使用[FromBody]或serializeArray()

No need to use [FromBody] or serializeArray()

    [HttpPost]
    public IActionResult UploadFilesAjax(MyViewModel xxx )
    {

这是我的html,以防万一:

This is my html, just in case:

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

<div id="file-list">
    <input type="file" name="file" class="file-select" accept="application/pdf,application">
    <input type="file" name="file" class="file-select" accept="application/pdf,application" />
</div>
<div id="fields">
    <input type="text" name="Email" />
</div>

<input type="button"
        id="submit"
        value="Upload Selected Files" />
</form>

这篇关于在ASP.NET Core MVC6中将文件和模型发布到控制器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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