表单上传文件
传统的文件上传是通过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参数进行序列化处理 这里必须falsecontentType: 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>
执行结果