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

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


当前回答

MemoryStream.GetBuffer() can return extra empty bytes at the end of the byte[], but you can fix that by using MemoryStream.ToArray() instead. However, I found this alternative to work perfectly for all file types:

using (var binaryReader = new BinaryReader(file.InputStream))
{
    byte[] array = binaryReader.ReadBytes(file.ContentLength);
}
Here's my full code:

Document Class:

public class Document
{
    public int? DocumentID { get; set; }
    public string FileName { get; set; }
    public byte[] Data { get; set; }
    public string ContentType { get; set; }
    public int? ContentLength { get; set; }

    public Document()
    {
        DocumentID = 0;
        FileName = "New File";
        Data = new byte[] { };
        ContentType = "";
        ContentLength = 0;
    }
}
File Download:

[HttpGet]
public ActionResult GetDocument(int? documentID)
{
    // Get document from database
    var doc = dataLayer.GetDocument(documentID);

    // Convert to ContentDisposition
    var cd = new System.Net.Mime.ContentDisposition
    {
        FileName = doc.FileName, 

        // Prompt the user for downloading; set to true if you want 
        // the browser to try to show the file 'inline' (display in-browser
        // without prompting to download file).  Set to false if you 
        // want to always prompt them to download the file.
        Inline = true, 
    };
    Response.AppendHeader("Content-Disposition", cd.ToString());

    // View document
    return File(doc.Data, doc.ContentType);
}
File Upload:

[HttpPost]
public ActionResult GetDocument(HttpPostedFileBase file)
{
    // Verify that the user selected a file
    if (file != null && file.ContentLength > 0)
    {
        // Get file info
        var fileName = Path.GetFileName(file.FileName);
        var contentLength = file.ContentLength;
        var contentType = file.ContentType;

        // Get file data
        byte[] data = new byte[] { };
        using (var binaryReader = new BinaryReader(file.InputStream))
        {
            data = binaryReader.ReadBytes(file.ContentLength);
        }

        // Save to database
        Document doc = new Document()
        {
            FileName = fileName,
            Data = data,
            ContentType = contentType,
            ContentLength = contentLength,
        };
        dataLayer.SaveDocument(doc);

        // Show success ...
        return RedirectToAction("Index");
    }
    else
    {
        // Show error ...
        return View("Foo");
    }
}
View (snippet):

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

其他回答

提供完整的解决方案

首先在MVC视图中使用.CShtml中的输入

<input type="file" id="UploadImg" /></br>
<img id="imgPreview" height="200" width="200" />

现在调用Ajax调用

  $("#UploadImg").change(function () {
    var data = new FormData();
    var files = $("#UploadImg").get(0).files;
    if (files.length > 0) {
        data.append("MyImages", files[0]);
    }

    $.ajax({
        // url: "Controller/ActionMethod"
        url: "/SignUp/UploadFile",
        type: "POST",
        processData: false,
        contentType: false,
        data: data,
        success: function (response)
        {
            //code after success
            $("#UploadPhoto").val(response);
            $("#imgPreview").attr('src', '/Upload/' + response);
        },
        error: function (er) {
            //alert(er);
        }

    });
});

控制器Json呼叫

[HttpGet]
public JsonResult UploadFile()
    {
        string _imgname = string.Empty;
        if (System.Web.HttpContext.Current.Request.Files.AllKeys.Any())
        {
            var pic = System.Web.HttpContext.Current.Request.Files["MyImages"];
            if (pic.ContentLength > 0)
            {
                var fileName = Path.GetFileName(pic.FileName);
                var _ext = Path.GetExtension(pic.FileName);

                _imgname = Guid.NewGuid().ToString();
                var _comPath = Server.MapPath("/MyFolder") + _imgname + _ext;
                _imgname = "img_" + _imgname + _ext;

                ViewBag.Msg = _comPath;
                var path = _comPath;
                tblAssignment assign = new tblAssignment();
                assign.Uploaded_Path = "/MyFolder" + _imgname + _ext;
                // Saving Image in Original Mode
                pic.SaveAs(path);
            }
        }
        return Json(Convert.ToString(_imgname), JsonRequestBehavior.AllowGet);
    }

我的方法和上面差不多,我将向您展示我的代码以及如何使用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;

尽管我在donnetfiddle上为你做了一个示例项目,但大多数答案似乎都足够合理

我正在使用LumenWorks.Framework进行CSV工作,但这不是必须的。

Demo

View

            @using (Html.BeginForm("Index", "Home", "POST")) 

            {
                <div class="form-group">

                        <label for="file">Upload Files:</label>
                        <input type="file" multiple name="files" id="files" class="form-control"/><br><br>
                        <input type="submit" value="Upload Files" class="form-control"/>
                </div>

控制器:

    [HttpPost]
    public ActionResult Index(HttpPostedFileBase upload)
    {
        if (ModelState.IsValid)
        {
            if (upload != null && upload.ContentLength > 0)
            {
                // Validation content length 
                if (upload.FileName.EndsWith(".csv") || upload.FileName.EndsWith(".CSV"))
                {
                    //extention validation 
                    ViewBag.Result = "Correct File Uploaded";
                }
            }
        }

        return View();
    }

请注意此代码仅用于上传图像。我使用HTMLHelper上传图像。在cshtml文件中放入以下代码

@using (Html.BeginForm("UploadImageAction", "Admin", FormMethod.Post, new { enctype = "multipart/form-data", id = "myUploadForm" }))
{
    <div class="controls">
       @Html.UploadFile("UploadImage")
    </div>
     <button class="button">Upload Image</button>
}

然后为Upload标记创建HTMLHelper

public static class UploadHelper
{
public static MvcHtmlString UploadFile(this HtmlHelper helper, string name, object htmlAttributes = null)
{
    TagBuilder input = new TagBuilder("input");
    input.Attributes.Add("type", "file");
    input.Attributes.Add("id", helper.ViewData.TemplateInfo.GetFullHtmlFieldId(name));
    input.Attributes.Add("name", helper.ViewData.TemplateInfo.GetFullHtmlFieldName(name));

    if (htmlAttributes != null)
    {
        var attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
        input.MergeAttributes(attributes);
    }

    return new MvcHtmlString(input.ToString());
   }
}

最后在行动中上传你的文件

        [AjaxOnly]
        [HttpPost]
        public ActionResult UploadImageAction(HttpPostedFileBase UploadImage)
        {
           string path = Server.MapPath("~") + "Files\\UploadImages\\" + UploadImage.FileName;
           System.Drawing.Image img = new Bitmap(UploadImage.InputStream);    
           img.Save(path);

           return View();
        }

另一种传输到字节[]的方法(用于保存到DB)。

@Arthur的方法工作得很好,但不能完美复制,因此MS Office文档在从数据库检索后可能无法打开。MemoryStream.GetBuffer()可以在字节[]的末尾返回额外的空字节,但可以使用MemoryStream.ToArray()来解决这个问题。然而,我发现这个替代方案可以完美地适用于所有文件类型:

using (var binaryReader = new BinaryReader(file.InputStream))
{
    byte[] array = binaryReader.ReadBytes(file.ContentLength);
}

这是我的完整代码:

文档类别:

public class Document
{
    public int? DocumentID { get; set; }
    public string FileName { get; set; }
    public byte[] Data { get; set; }
    public string ContentType { get; set; }
    public int? ContentLength { get; set; }

    public Document()
    {
        DocumentID = 0;
        FileName = "New File";
        Data = new byte[] { };
        ContentType = "";
        ContentLength = 0;
    }
}

文件下载:

[HttpGet]
public ActionResult GetDocument(int? documentID)
{
    // Get document from database
    var doc = dataLayer.GetDocument(documentID);

    // Convert to ContentDisposition
    var cd = new System.Net.Mime.ContentDisposition
    {
        FileName = doc.FileName, 

        // Prompt the user for downloading; set to true if you want 
        // the browser to try to show the file 'inline' (display in-browser
        // without prompting to download file).  Set to false if you 
        // want to always prompt them to download the file.
        Inline = true, 
    };
    Response.AppendHeader("Content-Disposition", cd.ToString());

    // View document
    return File(doc.Data, doc.ContentType);
}

文件上载:

[HttpPost]
public ActionResult GetDocument(HttpPostedFileBase file)
{
    // Verify that the user selected a file
    if (file != null && file.ContentLength > 0)
    {
        // Get file info
        var fileName = Path.GetFileName(file.FileName);
        var contentLength = file.ContentLength;
        var contentType = file.ContentType;

        // Get file data
        byte[] data = new byte[] { };
        using (var binaryReader = new BinaryReader(file.InputStream))
        {
            data = binaryReader.ReadBytes(file.ContentLength);
        }

        // Save to database
        Document doc = new Document()
        {
            FileName = fileName,
            Data = data,
            ContentType = contentType,
            ContentLength = contentLength,
        };
        dataLayer.SaveDocument(doc);

        // Show success ...
        return RedirectToAction("Index");
    }
    else
    {
        // Show error ...
        return View("Foo");
    }
}

视图(代码段):

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