(前言:这个问题是关于2011年发布的ASP.NET MVC 3.0,而不是关于2019年发布的ASP.NETCore 3.0)

我想用asp.net mvc上传文件。如何使用html输入文件控件上载文件?


当前回答

您不使用文件输入控件。ASP.NET MVC中未使用服务器端控件。查看下面的博客文章,其中说明了如何在ASP.NET MVC中实现这一点。

因此,您将首先创建一个HTML表单,其中包含文件输入:

@using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    <input type="file" name="file" />
    <input type="submit" value="OK" />
}

然后你会有一个控制器来处理上传:

public class HomeController : Controller
{
    // This action renders the form
    public ActionResult Index()
    {
        return View();
    }

    // This action handles the form POST and the upload
    [HttpPost]
    public ActionResult Index(HttpPostedFileBase file)
    {
        // Verify that the user selected a file
        if (file != null && file.ContentLength > 0) 
        {
            // extract only the filename
            var fileName = Path.GetFileName(file.FileName);
            // store the file inside ~/App_Data/uploads folder
            var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
            file.SaveAs(path);
        }
        // redirect back to the index action to show the form once again
        return RedirectToAction("Index");        
    }
}

其他回答

检查我的解决方案

public string SaveFile(HttpPostedFileBase uploadfile, string saveInDirectory="/", List<string> acceptedExtention =null)
{
    acceptedExtention = acceptedExtention ?? new List<String>() {".png", ".Jpeg"};//optional arguments

    var extension = Path.GetExtension(uploadfile.FileName).ToLower();

    if (!acceptedExtention.Contains(extension))
    {
        throw new UserFriendlyException("Unsupported File type");
    }
    var tempPath = GenerateDocumentPath(uploadfile.FileName, saveInDirectory);
    FileHelper.DeleteIfExists(tempPath);
    uploadfile.SaveAs(tempPath);

    var fileName = Path.GetFileName(tempPath);
    return fileName;
}

private string GenerateDocumentPath(string fileName, string saveInDirectory)
{
    System.IO.Directory.CreateDirectory(Server.MapPath($"~/{saveInDirectory}"));
    return Path.Combine(Server.MapPath($"~/{saveInDirectory}"), Path.GetFileNameWithoutExtension(fileName) +"_"+ DateTime.Now.Ticks + Path.GetExtension(fileName));
}

在基本控制器中添加这些函数,以便可以在所有控制器中使用它们

检查如何使用它

SaveFile(view.PassportPicture,acceptedExtention:new List<String>() { ".png", ".Jpeg"},saveInDirectory: "content/img/PassportPicture");

下面是一个完整的例子

[HttpPost]
public async Task<JsonResult> CreateUserThenGenerateToken(CreateUserViewModel view)
{// CreateUserViewModel contain two properties of type HttpPostedFileBase  
    string passportPicture = null, profilePicture = null;
    if (view.PassportPicture != null)
    {
        passportPicture = SaveFile(view.PassportPicture,acceptedExtention:new List<String>() { ".png", ".Jpeg"},saveInDirectory: "content/img/PassportPicture");
    }
    if (view.ProfilePicture != null)
    {
        profilePicture = SaveFile(yourHttpPostedFileBase, acceptedExtention: new List<String>() { ".png", ".Jpeg" }, saveInDirectory: "content/img/ProfilePicture");
    }
    var input = view.MapTo<CreateUserInput>();
    input.PassportPicture = passportPicture;
    input.ProfilePicture = profilePicture;


    var getUserOutput = await _userAppService.CreateUserThenGenerateToken(input);
    return new AbpJsonResult(getUserOutput);
    //return Json(new AjaxResponse() { Result = getUserOutput, Success = true });

}

您不使用文件输入控件。ASP.NET MVC中未使用服务器端控件。查看下面的博客文章,其中说明了如何在ASP.NET MVC中实现这一点。

因此,您将首先创建一个HTML表单,其中包含文件输入:

@using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    <input type="file" name="file" />
    <input type="submit" value="OK" />
}

然后你会有一个控制器来处理上传:

public class HomeController : Controller
{
    // This action renders the form
    public ActionResult Index()
    {
        return View();
    }

    // This action handles the form POST and the upload
    [HttpPost]
    public ActionResult Index(HttpPostedFileBase file)
    {
        // Verify that the user selected a file
        if (file != null && file.ContentLength > 0) 
        {
            // extract only the filename
            var fileName = Path.GetFileName(file.FileName);
            // store the file inside ~/App_Data/uploads folder
            var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
            file.SaveAs(path);
        }
        // redirect back to the index action to show the form once again
        return RedirectToAction("Index");        
    }
}

在视图中:

<form action="Categories/Upload" enctype="multipart/form-data" method="post">
    <input type="file" name="Image">
    <input type="submit" value="Save">
</form>

而控制器中的以下代码:

public ActionResult Upload()
{
    foreach (string file in Request.Files)
    {
       var hpf = this.Request.Files[file];
       if (hpf.ContentLength == 0)
       {
            continue;
       }

       string savedFileName = Path.Combine(
                AppDomain.CurrentDomain.BaseDirectory, "PutYourUploadDirectoryHere");
                savedFileName = Path.Combine(savedFileName, Path.GetFileName(hpf.FileName));

        hpf.SaveAs(savedFileName);
    }

    ...
}

我在做文件上传概念时也遇到过同样的错误。我知道开发人员为这个问题提供了很多答案。

尽管我回答这个问题的原因是,由于下面提到的疏忽错误,我犯了这个错误。

<input type="file" name="uploadedFile" />

在指定name属性时,请确保控制器参数也具有相同的名称值“uploadedFile”。这样地:

   [HttpPost]
            public ActionResult FileUpload(HttpPostedFileBase uploadedFile)
            {

            }

否则它不会被映射。

如果有人想用Ajax上传多个文件,下面是我的文章在Asp.NetMVC中使用Ajax进行多文件上传