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

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


当前回答

使用formdata上载文件

.cshtml文件

     var files = $("#file").get(0).files;
     if (files.length > 0) {
                data.append("filekey", files[0]);}


   $.ajax({
            url: '@Url.Action("ActionName", "ControllerName")', type: "POST", processData: false,
            data: data, dataType: 'json',
            contentType: false,
            success: function (data) {
                var response=data.JsonData;               
            },
            error: function (er) { }

        });

服务器端代码

if (System.Web.HttpContext.Current.Request.Files.AllKeys.Any())
                {
                    var pic = System.Web.HttpContext.Current.Request.Files["filekey"];
                    HttpPostedFileBase filebase = new HttpPostedFileWrapper(pic);
                    var fileName = Path.GetFileName(filebase.FileName);


                    string fileExtension = System.IO.Path.GetExtension(fileName);

                    if (fileExtension == ".xls" || fileExtension == ".xlsx")
                    {
                        string FileName = Guid.NewGuid().GetHashCode().ToString("x");
                        string dirLocation = Server.MapPath("~/Content/PacketExcel/");
                        if (!Directory.Exists(dirLocation))
                        {
                            Directory.CreateDirectory(dirLocation);
                        }
                        string fileLocation = Server.MapPath("~/Content/PacketExcel/") + FileName + fileExtension;
                        filebase.SaveAs(fileLocation);
}
}

其他回答

使用formdata上载文件

.cshtml文件

     var files = $("#file").get(0).files;
     if (files.length > 0) {
                data.append("filekey", files[0]);}


   $.ajax({
            url: '@Url.Action("ActionName", "ControllerName")', type: "POST", processData: false,
            data: data, dataType: 'json',
            contentType: false,
            success: function (data) {
                var response=data.JsonData;               
            },
            error: function (er) { }

        });

服务器端代码

if (System.Web.HttpContext.Current.Request.Files.AllKeys.Any())
                {
                    var pic = System.Web.HttpContext.Current.Request.Files["filekey"];
                    HttpPostedFileBase filebase = new HttpPostedFileWrapper(pic);
                    var fileName = Path.GetFileName(filebase.FileName);


                    string fileExtension = System.IO.Path.GetExtension(fileName);

                    if (fileExtension == ".xls" || fileExtension == ".xlsx")
                    {
                        string FileName = Guid.NewGuid().GetHashCode().ToString("x");
                        string dirLocation = Server.MapPath("~/Content/PacketExcel/");
                        if (!Directory.Exists(dirLocation))
                        {
                            Directory.CreateDirectory(dirLocation);
                        }
                        string fileLocation = Server.MapPath("~/Content/PacketExcel/") + FileName + fileExtension;
                        filebase.SaveAs(fileLocation);
}
}

我的方法和上面差不多,我将向您展示我的代码以及如何使用MYSSQL数据库。。。

数据库中的文档表-

int Id(PK),字符串Url,字符串描述,创建者,租户ID上传日期

上面的代码ID是主键,URL是文件的名称(末尾有文件类型),要在文档视图中输出的文件描述,CreatedBy是上载文件的人,tenncyId,dateUploaded

在视图中,必须定义enctype,否则它将无法正常工作。

@using (Html.BeginForm("Upload", "Document", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="input-group">
    <label for="file">Upload a document:</label>
    <input type="file" name="file" id="file" />
</div>
}

上面的代码将给你一个浏览按钮,然后在我的项目中,我有一个基本上名为IsValidImage的类,它只是检查文件大小是否在指定的最大大小之下,检查它是否是IMG文件,这都在类bool函数中。所以,如果true返回true。

public static bool IsValidImage(HttpPostedFileBase file, double maxFileSize, ModelState ms )
{
    // make sur the file isnt null.
    if( file == null )
        return false;

// the param I normally set maxFileSize is 10MB  10 * 1024 * 1024 = 10485760 bytes converted is 10mb
var max = maxFileSize * 1024 * 1024;

// check if the filesize is above our defined MAX size.
if( file.ContentLength > max )
    return false;

try
{
    // define our allowed image formats
    var allowedFormats = new[] { ImageFormat.Jpeg, ImageFormat.Png, ImageFormat.Gif, ImageFormat.Bmp };

    // Creates an Image from the specified data stream.      
    using (var img = Image.FromStream(file.InputStream))
    {
        // Return true if the image format is allowed
        return allowedFormats.Contains(img.RawFormat);
    }
}
catch( Exception ex )
{
    ms.AddModelError( "", ex.Message );                 
}
return false;   
}

因此,在控制器中:

if (!Code.Picture.IsValidUpload(model.File, 10, true))
{                
    return View(model);
}

// Set the file name up... Being random guid, and then todays time in ticks. Then add the file extension
// to the end of the file name
var dbPath = Guid.NewGuid().ToString() + DateTime.UtcNow.Ticks + Path.GetExtension(model.File.FileName);

// Combine the two paths together being the location on the server to store it
// then the actual file name and extension.
var path = Path.Combine(Server.MapPath("~/Uploads/Documents/"), dbPath);

// set variable as Parent directory I do this to make sure the path exists if not
// I will create the directory.
var directoryInfo = new FileInfo(path).Directory;

if (directoryInfo != null)
    directoryInfo.Create();

// save the document in the combined path.
model.File.SaveAs(path);

// then add the data to the database
_db.Documents.Add(new Document
{
    TenancyId = model.SelectedTenancy,
    FileUrl = dbPath,
    FileDescription = model.Description,
    CreatedBy = loggedInAs,
    CreatedDate = DateTime.UtcNow,
    UpdatedDate = null,
    CanTenantView = true
});

_db.SaveChanges();
model.Successfull = true;

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

检查我的解决方案

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 });

}

通常,您还希望传递一个视图模型,而不仅仅是一个文件。在下面的代码中,您将发现一些其他有用的功能:

检查文件是否已附加检查文件大小是否为0检查文件大小是否大于4 MB检查文件大小是否小于100字节检查文件扩展名

可以通过以下代码完成:

[HttpPost]
public ActionResult Index(MyViewModel viewModel)
{
    // if file's content length is zero or no files submitted

    if (Request.Files.Count != 1 || Request.Files[0].ContentLength == 0)
    {
        ModelState.AddModelError("uploadError", "File's length is zero, or no files found");
        return View(viewModel);
    }

    // check the file size (max 4 Mb)

    if (Request.Files[0].ContentLength > 1024 * 1024 * 4)
    {
        ModelState.AddModelError("uploadError", "File size can't exceed 4 MB");
        return View(viewModel);
    }

    // check the file size (min 100 bytes)

    if (Request.Files[0].ContentLength < 100)
    {
        ModelState.AddModelError("uploadError", "File size is too small");
        return View(viewModel);
    }

    // check file extension

    string extension = Path.GetExtension(Request.Files[0].FileName).ToLower();

    if (extension != ".pdf" && extension != ".doc" && extension != ".docx" && extension != ".rtf" && extension != ".txt")
    {
        ModelState.AddModelError("uploadError", "Supported file extensions: pdf, doc, docx, rtf, txt");
        return View(viewModel);
    }

    // extract only the filename
    var fileName = Path.GetFileName(Request.Files[0].FileName);

    // store the file inside ~/App_Data/uploads folder
    var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);

    try
    {
        if (System.IO.File.Exists(path))
            System.IO.File.Delete(path);

        Request.Files[0].SaveAs(path);
    }
    catch (Exception)
    {
        ModelState.AddModelError("uploadError", "Can't save file to disk");
    }

    if(ModelState.IsValid)
    {
        // put your logic here

        return View("Success");
    }

    return View(viewModel);         
}

确保你有

@Html.ValidationMessage("uploadError")

在您的视图中查看验证错误。

还要记住,默认最大请求长度为4MB(maxRequestLength=4096),要上载更大的文件,必须在web.config中更改此参数:

<system.web>
    <httpRuntime maxRequestLength="40960" executionTimeout="1100" />

(此处40960=40 MB)。

执行超时是秒的整数。您可能希望将其更改为允许上传大量文件。