表单上传文件
传统的文件上传是通过form表单,俗话说不关注实际问题的解决方法都是假把式,那么我就模拟一个用户注册的功能。
观察如下代码:
[HttpPost]
public ActionResult Upload(string username, string password, string realName, string address, HttpPostedFileBase picture)
{
//保存文件
string fileName = Guid.NewGuid().ToString() + ".png";
var realPath = Server.MapPath("/Upload/" + fileName);
picture.SaveAs(realPath);
//更新数据库
using(SqlConnection conn = new SqlConnection("Data Source=DESKTOP-2HL1HGR\\SQL2014;Initial Catalog=TestDemo;Integrated Security=True"))
{
conn.Open();
string sql = string.Format("INSERT INTO tb_user (Username, Password, RealName, Address, FileName) VALUES ('{0}', '{1}', '{2}', '{3}', '{4}')",
username, password, realName, address, fileName);
SqlCommand cmd = new SqlCommand(sql, conn);
int result = cmd.ExecuteNonQuery();
if(result > 0)
{
return Json("Success");
}else
{
return Json("Fail");
}
}
}
<h1>用户注册</h1>
<form action="/Test/Upload" method="post" enctype="multipart/form-data">
<table class="table table-hover">
<tr>
<td><b>用户名称</b></td>
<td><input type="text" id="username" name="username" class="form-control" /></td>
</tr>
<tr>
<td><b>用户密码</b></td>
<td><input type="password" id="password" name="password" class="form-control" /></td>
</tr>
<tr>
<td><b>真实姓名</b></td>
<td><input type="text" id="realName" name="realName" class="form-control" /></td>
</tr>
<tr>
<td><b>家庭住址</b></td>
<td><input type="text" id="address" name="address" class="form-control" /></td>
</tr>
<tr>
<td><b>用户头像</b></td>
<td><input type="file" id="picture" name="picture" class="form-control" /></td>
</tr>
<tr>
<td colspan="2">
<input type="submit" id="btnEdit" class="btn btn-primary" value="注册" />
<input type="reset" class="btn btn-danger" value="重置" />
</td>
</tr>
</table>
</form>
通过表单可以顺利的上传文件,但是这样有个很明显的缺陷就是不能在页面上执行回调函数,所以我们一般采用ajax的方式进行文件上传。
ajax文件上传
为了方便传参我们定义一个模型类User
public class User
{
public int Id { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string RealName { get; set; }
public string Address { get; set; }
}
然后控制类的方法中就把参数定义为User和file即可
[HttpPost]
public ActionResult Upload(User user, HttpPostedFileBase FileName)
{
//保存文件
string fileName = Guid.NewGuid().ToString() + ".png";
var realPath = Server.MapPath("/Upload/" + fileName);
FileName.SaveAs(realPath);
//更新数据库
using (SqlConnection conn = new SqlConnection("Data Source=DESKTOP-2HL1HGR\\SQL2014;Initial Catalog=TestDemo;Integrated Security=True"))
{
conn.Open();
string sql = string.Format("INSERT INTO tb_user (Username, Password, RealName, Address, FileName) VALUES ('{0}', '{1}', '{2}', '{3}', '{4}')",
user.Username, user.Password, user.RealName, user.Address, fileName);
SqlCommand cmd = new SqlCommand(sql, conn);
int result = cmd.ExecuteNonQuery();
if(result > 0)
{
return Json("Success");
}else
{
return Json("Fail");
}
}
}
重点就是前台方法需要实例化一个FormData类,用于存放表单的数据,同时要在ajax中设置processData和contentType为false,否则不会跳转到后台控制层。
<h1>用户注册</h1>
<form id="form1">
<table class="table table-hover">
<tr>
<td><b>用户名称</b></td>
<td><input type="text" id="Username" name="Username" class="form-control" /></td>
</tr>
<tr>
<td><b>用户密码</b></td>
<td><input type="password" id="Password" name="Password" class="form-control" /></td>
</tr>
<tr>
<td><b>真实姓名</b></td>
<td><input type="text" id="RealName" name="RealName" class="form-control" /></td>
</tr>
<tr>
<td><b>家庭住址</b></td>
<td><input type="text" id="Address" name="Address" class="form-control" /></td>
</tr>
<tr>
<td><b>用户头像</b></td>
<td>
<input type="file" id="FileName" name="FileName" class="form-control" />
</td>
</tr>
<tr>
<td colspan="2">
<input type="button" id="btnConfirm" class="btn btn-primary" value="注册" />
<input type="reset" class="btn btn-danger" value="重置" />
</td>
</tr>
</table>
</form>
<script>
$(function () {
$("#btnConfirm").click(function () {
var formData = new FormData();
formData.append("Username", $("#Username").val());
formData.append("Password", $("#Password").val());
formData.append("RealName", $("#RealName").val());
formData.append("Address", $("#Address").val());
formData.append("FileName", $("#FileName")[0].files[0]);
$.ajax({
url: "/Test/Upload",
type: "post",
dataType: "json",
data: formData,
processData: false, // 告诉jQuery不要去处理发送的数据,用于对data参数进行序列化处理 这里必须false
contentType: false, // 告诉jQuery不要去设置Content-Type请求头
success: function (result) {
if (result == "Success") {
console.log("注册成功!");
} else {
console.log("注册失败!");
}
}
})
})
})
</script>
执行结果
点击注册之后
在Upload文件夹之中
查看数据库
数据库图片取出
我在数据库中的图片是一个路径,准确的说是一个文件名,因为我的图片都是存在项目目录的Upload文件夹之中的,所以我们在取出图片的时候,可以先自己写个文件路径前缀,加上数据库的文件名就可以正常取出了。
[HttpPost]
public ActionResult GetImg()
{
using (SqlConnection conn = new SqlConnection("Data Source=DESKTOP-2HL1HGR\\SQL2014;Initial Catalog=TestDemo;Integrated Security=True"))
{
conn.Open();
string sql = "SELECT FileName FROM tb_user WHERE Id=1";
SqlCommand cmd = new SqlCommand(sql, conn);
return Json(cmd.ExecuteScalar().ToString());
}
}
<h2>Index2</h2>
<div id="showImg">
</div>
<script>
$(function () {
$.ajax({
type: "post",
url: "/Test/GetImg",
dataType: "json",
success: function (result) {
var htmlStr = "<img src='/Upload/" + result + "'>";
$("#showImg").empty().append(htmlStr);
}
})
})
</script>
执行结果