如果你仅仅只有Asp.net Web Forms背景转而学习Asp.net MVC的,我想你的第一个经历或许是那些曾经让你的编程变得愉悦无比的服务端控件都驾鹤西去了.FileUpload就是其中一个,而这个控件的缺席给我们带来一些小问题。这篇文章主要说如何在Asp.net MVC中上传文件,然后如何再从服务器中把上传过的文件下载下来.
在Web Forms中,当你把一个FileUpload控件拖到设计器中,你或许没有注意到在生成的HTML中会在form标签中加入一条额外属性enctype="multipart/form-data". 而FileUpload控件本身会生成为<input type=”file” />,在MVC的view里,有许多种方法可以做到同样效果,第一种的HTML如下:
<form action="/" method="post" enctype="multipart/form-data">
<input type="file" name="FileUpload1" /><br />
<input type="submit" name="Submit" id="Submit" value="Upload" />
</form>
注意form标签已经包括了enctype标签,而method属性则设为”post”,这样设置并不多于因为默认的提交时通过HTTP get方式进行的。下面这种方式,使用Html.BeginForm()扩展方法,会生成和上面同样的HTML:
<%
using (Html.BeginForm("", "home", FormMethod.Post, new {enctype="multipart/form-data"}))
{%>
<input type="file" name="FileUpload1" /><br />
<input type="submit" name="Submit" id="Submit" value="Upload" />
<% }%>
注意<input type=”file”>标签的name属性,我们在后面再讨论
OK,现在我们可以浏览本地文件然后通过Upload提交按钮将文件提交到服务器端,下一步就是在服务器端处理上传的文件,在使用fileUpload控件时,你可以很轻松的通过FileUpload的hasFile方法来查看文件是否被上传。但是在Asp.net MVC中貌似就不是这么方便了,你会和原始的HTTP更接近一些,然而,一个扩展方法可以处理这些:
public static bool HasFile(this HttpPostedFileBase file)
{
return (file != null && file.ContentLength > 0) ? true : false;
}
当你看到对应的Controller类的代码时,你会发现Request对象作为HttpRequestBase类型的一个属性存在。HttpReuqestBase其实是HTTP请求的一个封装,暴漏了很多属性,包括Files collection(其实是HttpFileCollectionBase的集合),在集合中的每一个元素都是HttpPostedFileBase的集合,扩展方法是用于确保上传的文件是否存在。实际上,这和FileUpload.HasFile()方法的工作原理一致。
在Controller Action中使用起来其实很容易:
public class HomeController : Controller
{
public ActionResult Index()
{
foreach (string upload in Request.Files)
{
if (!Request.Files[upload].HasFile()) continue;
string path = AppDomain.CurrentDomain.BaseDirectory + "uploads/";
string filename = Path.GetFileName(Request.Files[upload].FileName);
Request.Files[upload].SaveAs(Path.Combine(path, filename));
}
return View();
}
}
多文件上传
或许你已经比我更早的想到如何更好的将Request.Files作为一个集合使用。这意味着它不仅仅只能容纳一个文件,而能容纳多个,我们将上面的View改为如下:
<%
using (Html.BeginForm("", "home", FormMethod.Post, new {enctype="multipart/form-data"}))
{%>
<input type="file" name="FileUpload1" /><br />
<input type="file" name="FileUpload2" /><br />
<input type="file" name="FileUpload3" /><br />
<input type="file" name="FileUpload4" /><br />
<input type="file" name="FileUpload5" /><br />
<input type="submit" name="Submit" id="Submit" value="Upload" />
<% }%>
效果如下:
在Controller的代码中已经检查了是否所有的文件上传框中都有文件,所以即使对于多文件上传,我们也不再需要修改Controller的代码,注意每一个<input type=”file”>都有不同的name属性,如果你需要调用其中一个,比如说,你需要引用第三个输入框只需要使用:Request.Files["FileUpload3"].
存入数据库
在你冲我狂吼”关注点分离”之前,我想声明下面的代码仅仅用于作为说明功能.我将ADO.Net的代码放入Controller action中,但我们都知道,这并不好。数据访问的代码应该放在Model中某个部分的数据访问层中.但是,下面这段代码仅仅可以给大家怎样将上传的文件存入数据库中一个更直观的印象,首先,我们需要创建一个数据表(FileTest)并创建一个表:FileStore
CREATE TABLE [dbo].[FileStore](
[ID] [int] IDENTITY(1,1) NOT NULL,
[FileContent] [image] NOT NULL,
[MimeType] [nvarchar](50) NOT NULL,
[FileName] [nvarchar](50) NOT NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
FileContent域是image数据类型,用于存储以二进制数据形成的文件,而Index Action改为:
public ActionResult Index()
{
foreach (string upload in Request.Files)
{
if (!Request.Files[upload].HasFile()) continue;
string mimeType = Request.Files[upload].ContentType;
Stream fileStream = Request.Files[upload].InputStream;
string fileName = Path.GetFileName(Request.Files[upload].FileName);
int fileLength = Request.Files[upload].ContentLength;
byte[] fileData = new byte[fileLength];
fileStream.Read(fileData, 0, fileLength);
const string connect = @"Server=.\SQLExpress;Database=FileTest;Trusted_Connection=True;";
using (var conn = new SqlConnection(connect))
{
var qry = "INSERT INTO FileStore (FileContent, MimeType, FileName) VALUES (@FileContent, @MimeType, @FileName)";
var cmd = new SqlCommand(qry, conn);
cmd.Parameters.AddWithValue("@FileContent", fileData);
cmd.Parameters.AddWithValue("@MimeType", mimeType);
cmd.Parameters.AddWithValue("@FileName", fileName);
conn.Open();
cmd.ExecuteNonQuery();
}
}
return View();
}
修改后的代码会以循环的方式遍历Web页面中所有的上传文件,并检查<input type=”file”>中是否已经加入文件,然后,从文件中提取出3个信息:文件名,MIME类型(文件的类型),HTTP Request中的二进制流。二进制数据被转换为byte数组,并以image数据类型存入数据库。MIME类型和文件名对于用户从数据库中提取文件来说非常重要。
将数据库中的文件返回给用户:
你如何将文件传送给用户取决于你最开始如何存储它,如果你将文件存入数据库,你会用流的方式将文件返还给用户,如果你将文件存在硬盘中,你只需要提供一个超链接即可,或者也可以以流的方式。每当你需要以流的方式将文件送到浏览器中,你都的使用到File()方法的重载(而不是使用我们先前一直使用的View()方法),对于File()方法有3类返回类型:FilePathResult,FileContentResult和FileStreamResult,第一种类型用于直接从磁盘返回文件;第二种类型用于将byte数组返回客户端;而第三种方式将已经生成并打开的流对象的内容返回客户端。
如果你还记得的话,我们将上传的文件存入了数据库,并以byte数组的形式存入FileContent域内.而当需要提取时,它仍然会以一个byte数组进行提取,这意味着我们使用返回FileContentResult的File()重载,如果我们想让提取的文件名更有意义,我们使用接受3个参数的重载,三个参数是:byte数组,MIME类型,文件名:
public FileContentResult GetFile(int id)
{
SqlDataReader rdr; byte[] fileContent = null;
string mimeType = "";string fileName = "";
const string connect = @"Server=.\SQLExpress;Database=FileTest;Trusted_Connection=True;";
using (var conn = new SqlConnection(connect))
{
var qry = "SELECT FileContent, MimeType, FileName FROM FileStore WHERE ID = @ID";
var cmd = new SqlCommand(qry, conn);
cmd.Parameters.AddWithValue("@ID", id);
conn.Open();
rdr = cmd.ExecuteReader();
if (rdr.HasRows)
{
rdr.Read();
fileContent = (byte[])rdr["FileContent"];
mimeType = rdr["MimeType"].ToString();
fileName = rdr["FileName"].ToString();
}
}
return File(fileContent, mimeType, fileName);
}
在View中最简单的使用来使用这个Action只需提供一个超链接:
<a href="/GetFile/1">Click to get file</a>
如果在数据库中存储的图片是图片类型,和使用超链接不同的是,我们通过指向Controller action的一个带有src属性的<image>标签来获取:
<img src="/GetFile/1" alt="My Image" />
下面再让我们来看看使用FilePathResult(用于从硬盘提取文件)是多简单的事:
public FilePathResult GetFileFromDisk()
{
string path = AppDomain.CurrentDomain.BaseDirectory + "uploads/";
string fileName = "test.txt";
return File(path + fileName, "text/plain", "test.txt");
}
而这也可以用过超链接提取:
<a href="/GetFileFromDisk">Click to get file</a>
而最后一个选择FileStreamResult也可以从磁盘中提取文件:
public FileStreamResult StreamFileFromDisk()
{
string path = AppDomain.CurrentDomain.BaseDirectory + "uploads/";
string fileName = "test.txt";
return File(new FileStream(path + fileName, FileMode.Open), "text/plain", fileName);
}
FilePathResult和FileStreamResult的区别是什么?我们又该如何取舍呢?主要的区别是FilePathResult使用HttpResponse.TransmitFile来将文件写入Http输出流。这个方法并不会在服务器内存中进行缓冲,所以这对于发送大文件是一个不错的选择。他们的区别很像DataReader和DataSet的区别。于此同时, TransmitFile还有一个bug,这可能导致文件传到客户端一半就停了,甚至无法传送。而FileStreamResult在这方面就很棒了。比如说:返回Asp.net Chart 控件在内存中生成的图表图片,而这并不需要将图片存到磁盘中.
分享到:
相关推荐
ASP.NET MVC 文件管理功能Demo是基于ASP.NET MVC框架和Easy-UI前端库开发的一个实践项目,旨在实现对本地文件系统的全面操作。这个Demo涵盖了多种文件操作功能,包括上传、下载、复制、粘贴、压缩以及重命名等,使得...
ASP.NET MVC 是一个用于构建动态网站的开源框架,它基于模型-视图-控制器(Model-View-Controller)设计模式,使得开发过程更加模块化、易于理解和...通过不断实践和学习,你将在ASP.NET MVC文件上传方面变得更加熟练。
- **服务器端集成**:需要与后端(如ASP.NET MVC控制器)配合,处理文件上传的接收和存储。 4. **ASP.NET MVC中的文件上传**: - **HttpPostedFileBase**:ASP.NET MVC提供的一种类型,用于接收通过HTTP POST方式...
ASP.NET MVC中的文件上传可以通过`HttpPostedFileBase`类来处理,这是ASP.NET MVC专门用于处理上传文件的类。在表单中,我们需使用`<input type="file">`元素来让用户选择要上传的文件,并确保表单的`enctype`属性...
ASP.NET MVC 文件上传是Web应用程序开发中的一个常见需求,它涉及到客户端与服务器之间的数据交互,尤其是处理用户上传的文件。本示例将详细介绍如何在ASP.NET MVC框架下实现这一功能,包括图片保存到数据库、从...
ASP.NET MVC 实现文件上传下载功能实例教程 一、概述 在 ASP.NET 程序开发中,文件上传和下载功能非常常见。 Asp.net.Mvc 框架提供了多种方式来实现文件上传和下载功能。本文将通过实例形式来实现文件上传和下载...
综上所述,Asp.net MVC结合Aspose和PDFObject.js实现在线预览功能,涵盖了后端的文件处理、前端的展示技术以及安全和性能的考量,是一个完整的系统设计过程。通过这样的实现方式,用户可以在浏览器中便捷地查看各种...
在.NET MVC框架中,我们可以利用Plupload来构建用户友好的文件上传功能,提供断点续传、批量上传、进度条显示等特性。本示例将详细介绍如何在.NET MVC项目中集成并使用Plupload。 1. **Plupload组件介绍** ...
### ASP.NET MVC 处理文件的上传下载 #### 引言 在开发Web应用程序时,文件的上传与下载是一项常见的需求。对于从ASP.NET Web Forms背景转入ASP.NET MVC的开发者而言,由于MVC架构的不同,原先熟悉的服务端控件如`...
在这个场景中,我们探讨的是如何利用ASP.NET MVC实现批量和分段文件上传,并且在上传过程中展示进度。这通常涉及到前端的JavaScript技术,特别是HTML5的File API和FormData对象,以及后端的ASP.NET MVC控制器处理。 ...
2. **HttpPostedFileBase** 类型:在ASP.NET MVC中,`HttpPostedFileBase`是处理文件上传的核心类,它继承自`System.Web.HttpFileBase`。在控制器的Action方法中,可以使用该类型作为参数接收上传的文件。 3. **...
在Asp.net MVC框架中,处理文件的上传和下载是常见的功能需求,尤其...通过以上步骤,开发者可以在Asp.net MVC应用中实现完整的文件上传和下载功能。理解并熟练运用这些知识点,将有助于构建高效、安全的文件管理系统。
环境 Asp.Net Mvc3 Vs2010 使用的脚本 jquery-1.5.1.min.js 、jquery.flash.js、 jquery.jqUploader.js 配置Webconfig ...
在IT行业中,C# ASP.NET MVC框架是一种广泛用于构建Web应用程序的技术栈,它结合了C#编程语言、ASP.NET框架以及Model-View-Controller(MVC)设计模式。本篇文章将深入探讨如何在C# ASP.NET MVC环境中实现在线拍照...
- 在控制器中,需要创建两个Action方法,一个用于处理视图操作,另一个专门用于处理文件上传。 - 在模型中,创建一个Entity类用于表示数据库表中的记录,并定义必要的数据访问方法。 - 可能包含一个将DataTable转换...
在ASP.NET MVC框架中,处理大文件上传是一个常见的挑战,因为单个文件的大小可能会超出服务器或HTTP协议的限制。为了克服这个问题,开发者通常采用文件分片上传的技术,即将大文件分割成多个小块(片段),然后逐个...
文件上传在Web应用中很常见,ASP.NET MVC2提供了方便的API来处理文件上传,包括验证文件大小和类型的安全控制。 最后,ASP.NET MVC2与ASP.NET其他技术如Web Forms、AJAX和jQuery等可以无缝集成,使你能够利用这些...
在Asp.Net MVC中,使用jQuery和AJAX进行文件上传需要额外的插件,如jQuery Form Plugin。这个插件可以处理表单提交,包括文件上传。 七、异常处理和验证 在AJAX请求中,我们可以利用ASP.NET MVC的Validation ...
在C# ASP.NET MVC框架中实现多图片上传是一项常见的任务,尤其在开发涉及用户交互、内容管理和电子商务的应用程序时。这个技术涉及到文件处理、表单提交、数据验证、存储优化等多个方面。以下是对这一主题的详细说明...
本文将深入探讨如何在Asp.Net Mvc环境中实现多图上传功能,包括前端交互、后端处理以及文件存储策略。 一、前端实现 1. 表单设计:创建一个HTML表单,包含多个`<input type="file">`元素,允许用户选择多张图片。...