简体   繁体   English

在 ASP.NET MVC 6 中上传文件

[英]Upload File in ASP.NET MVC 6

I'm having trouble ironing out the file/image upload in ASP.NET MVC 6. Most tutorials appear to be outdated, and even some of the new ones seem to reference things that don't make sense.我在解决 ASP.NET MVC 6 中的文件/图像上传时遇到了麻烦。大多数教程似乎已经过时,甚至一些新教程似乎引用了没有意义的东西。

In my view:在我看来:

<div class="form-group">
    @using (Html.BeginForm("Create", "PostNin", FormMethod.Post, new { enctype = "multipart/form-data" }))
    {
        <label asp-for="NinImageString" class="control-label"></label>
        <input type="file" name="files" class="form-control" />
    }

    @*<input asp-for="NinImageString" class="form-control" />
    <span asp-validation-for="NinImageString" class="text-danger"></span>*@
</div>
<div class="form-group">
    <label asp-for="NinImageCaption" class="control-label"></label>
    <input asp-for="NinImageCaption" class="form-control" />
    <span asp-validation-for="NinImageCaption" class="text-danger"></span>
</div>

And then in my controller:然后在我的控制器中:

// GET: PostNins/Create
public IActionResult Create()
{
    return View();
}

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Id,NinFk,NinDigit,NinImageString,NinImageCaption,NinNote")] PostNin postNin, IFormFile files)
{
    // need code here
        
    if (ModelState.IsValid)
    {
        _context.Add(postNin);
        await _context.SaveChangesAsync();
        return RedirectToAction(nameof(Index));
    }

    return View(postNin);
}

My understanding is that I have to use IFormFile to pull this off.我的理解是我必须使用IFormFile来实现这一点。

I would like to upload an image with a caption, and store it into the application folder NinImages where I can access it later.我想上传带有标题的图像,并将其存储到应用程序文件夹NinImages ,以便稍后访问。 I suppose I have questions about that too, but that's for another question.我想我对此也有疑问,但那是另一个问题。

My understanding is that I have to somehow save a copy of the image into the directory system, under wwwroot, then save the path of the file as a string to the database.我的理解是我必须以某种方式将图像的副本保存到目录系统中,在 wwwroot 下,然后将文件的路径作为字符串保存到数据库中。

SOLUTION:解决方案:

My new controller looks like below.我的新控制器如下所示。 As a note, the fileTime is only to assign a unique value to each upload, to avoid duplicates.注意,fileTime 只是为每次上传分配一个唯一值,以避免重复。 This works in this case because only one file can be uploaded at a time.这在这种情况下有效,因为一次只能上传一个文件。

[HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Create([Bind("Id,NinFk,NinDigit,NinImageString,NinImageCaption,NinNote")] PostNin postNin, IFormFile uploadFile)
    {


        if (uploadFile != null && uploadFile.Length > 0)
        {
            var fileTime = DateTime.UtcNow.ToString("yyMMddHHmmss");
            var fileName = fileTime + Path.GetFileName(uploadFile.FileName);
            var filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/NinFileUploads", fileName);

            postNin.NinImageString = filePath;
            _context.PostNins.Add(postNin);
            _context.SaveChanges();

            using (var fileStream = new FileStream(filePath, FileMode.Create))
            {
                await uploadFile.CopyToAsync(fileStream);
            }
            //if (ModelState.IsValid)
            //{
            //    _context.Add(postNin);
            //    await _context.SaveChangesAsync();
            //    return RedirectToAction(nameof(Index));
            //}
            return RedirectToAction(nameof(Index));

        }
        return View(postNin);

Here is a demo work:这是一个演示工作:

PostNin Class: PostNin 类:

public class PostNin
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string ImagePath { get; set; }
    }

Controller:控制器:

public async Task<bool> Create(PostNin postNin,IFormFile upload)
        {     
                if (upload != null && upload.Length > 0)
                {                
                    var fileName = Path.GetFileName(upload.FileName);
                    var filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/images", fileName);
                    postNin.ImagePath = filePath;
                    _context.PostNins.Add(postNin);
                    _context.SaveChanges();
                    using (var fileSrteam = new FileStream(filePath, FileMode.Create))
                    {
                        await upload.CopyToAsync(fileSrteam);
                    }
                    return true;
                }
                return false;
        }

Result:结果: 在此处输入图片说明

change the name of the file upload control to files将文件上传控件的名称更改为 files

<input type="file" name="files" class="form-control" />

add [FromForm] before IFormFile files first and try if it works首先在 IFormFile 文件之前添加 [FromForm] 并尝试它是否有效

Create([Bind("Id,NinFk,NinDigit,NinImageString,NinImageCaption,NinNote")] PostNin postNin, [FromForm]IFormFile files)

if it not working try to add new IFormFile files property to PostNin class or create a new class as a model for this action and add [FromForm] before it on the action parameter.如果它不起作用,请尝试将新的 IFormFile 文件属性添加到 PostNin 类或创建一个新类作为此操作的模型,并在操作参数之前添加 [FromForm]。

public class PostNinModel {
....
public IFormFile files { get; set; }
...
}

Create([FromForm] PostNinModel postNin)

You need to set the name attribute for the input element same as Create method parameter, in this solution name attribute and Create method parameter set to uploadFile您需要为 input 元素设置与 Create 方法参数相同的 name 属性,在此解决方案中 name 属性和 Create 方法参数设置为uploadFile

HTML HTML

<input type="file" name="uploadFile" class="form-control" />

CS CS

Create([Bind("Id,NinFk,NinDigit,NinImageString,NinImageCaption,NinNote")] PostNin postNin, IFormFile uploadFile)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM