【译】MVC3 20个秘方-(11)通过表单上传文件

来源:未知 责任编辑:智问网络 发表时间:2013-09-26 23:49 点击:

 

 

问题

你希望允许用户在你的网站上传并保存文件。

解决方案

通过HttpPostedFileBase.实现上传文件和保存到磁盘。

讨论

在接下来的例子里,之前创建的去添加和更新图书的View将被更新成允许用户选择一个文件并且上传缩略图文件。作为开始,Book/Create  view 应该被更新,改变From的编码类型并且为缩略图字段替换掉脚手架textbox。代码如下:

@model MvcApplication.Models.Book

@{

    ViewBag.Title = "Create";

}

<h2>

    Create</h2>

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")"

type="text/javascript"></script>

<script src="

@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"

type="text/javascript"></script>

@using (Html.BeginForm("Create", "Books", FormMethod.Post,

new { enctype = "multipart/form-data" }))

{

    @Html.ValidationSummary(true)

    <fieldset>

        <legend>Book</legend>

        <div class="editor-label">

            @Html.LabelFor(model => model.Title)

        </div>

        <div class="editor-field">

            @Html.EditorFor(model => model.Title)

            @Html.ValidationMessageFor(model => model.Title)

        </div>

        <div class="editor-label">

            @Html.LabelFor(model => model.Isbn)

        </div>

        <div class="editor-field">

            @Html.EditorFor(model => model.Isbn)

            @Html.ValidationMessageFor(model => model.Isbn)

        </div>

        <div class="editor-label">

            @Html.LabelFor(model => model.Summary)

        </div>

        <div class="editor-field">

            @Html.EditorFor(model => model.Summary)

            @Html.ValidationMessageFor(model => model.Summary)

        </div>

        <div class="editor-label">

            @Html.LabelFor(model => model.Author)

        </div>

        <div class="editor-field">

            @Html.EditorFor(model => model.Author)

            @Html.ValidationMessageFor(model => model.Author)

        </div>

        <div class="editor-label">

            @Html.LabelFor(model => model.Thumbnail)

        </div>

        <div class="editor-field">

            <input type="file" name="file" />

            @Html.ValidationMessageFor(model => model.Thumbnail)

        </div>

        <div class="editor-label">

            @Html.LabelFor(model => model.Price)

        </div>

        <div class="editor-field">

            @Html.EditorFor(model => model.Price)

            @Html.ValidationMessageFor(model => model.Price)

        </div>

        <div class="editor-label">

            @Html.LabelFor(model => model.Published)

        </div>

        <div class="editor-field">

            @Html.EditorFor(model => model.Published)

            @Html.ValidationMessageFor(model => model.Published)

        </div>

        <p>

            <input type="submit" value="Create" />

        </p>

    </fieldset>

}

<div>

    @Html.ActionLink("Back to List", "Index")

</div>

Book/Edit view 也应该以相同的方式被更新,除了添加一个hidden字段(在旧的thumbnail那)。这将用于在BookController中上传新文件之前删除旧的文件。代码如下:

@model MvcApplication.Models.Book

@{

    ViewBag.Title = "Edit";

}

<h2>

    Edit</h2>

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")"

type="text/javascript"></script>

<script src="

@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"

type="text/javascript"></script>

@using (Html.BeginForm("Edit", "Books", FormMethod.Post,

new { enctype = "multipart/form-data" }))

{

    @Html.ValidationSummary(true)

    <fieldset>

        <legend>Book</legend>

        @Html.HiddenFor(model => model.ID)

        <div class="editor-label">

            @Html.LabelFor(model => model.Title)

        </div>

        <div class="editor-field">

            @Html.EditorFor(model => model.Title)

            @Html.ValidationMessageFor(model => model.Title)

        </div>

        <div class="editor-label">

            @Html.LabelFor(model => model.Isbn)

        </div>

        <div class="editor-field">

            @Html.EditorFor(model => model.Isbn)

            @Html.ValidationMessageFor(model => model.Isbn)

        </div>

        <div class="editor-label">

            @Html.LabelFor(model => model.Summary)

        </div>

        <div class="editor-field">

            @Html.EditorFor(model => model.Summary)

            @Html.ValidationMessageFor(model => model.Summary)

        </div>

        <div class="editor-label">

            @Html.LabelFor(model => model.Author)

        </div>

        <div class="editor-field">

            @Html.EditorFor(model => model.Author)

            @Html.ValidationMessageFor(model => model.Author)

        </div>

        <div class="editor-label">

            @Html.LabelFor(model => model.Thumbnail)

        </div>

        <div class="editor-field">

            <input type="file" name="file" />

            @Html.HiddenFor(model => model.Thumbnail)

            @Html.ValidationMessageFor(model => model.Thumbnail)

        </div>

        <div class="editor-label">

            @Html.LabelFor(model => model.Price)

        </div>

        <div class="editor-field">

            @Html.EditorFor(model => model.Price)

            @Html.ValidationMessageFor(model => model.Price)

        </div>

        <div class="editor-label">

            @Html.LabelFor(model => model.Published)

        </div>

        <div class="editor-field">

            @Html.EditorFor(model => model.Published)

            @Html.ValidationMessageFor(model => model.Published)

        </div>

        <p>

            <input type="submit" value="Save" />

        </p>

    </fieldset>

}

<div>

    @Html.ActionLink("Back to List", "Index")

</div>

由于BooksController中Create和edit功能都是保存上传文件,为了避免重复代码,我们将创建一个新的类。这个类将被创建在Utils文件夹中。Utils文件夹->右击并选择添加→类。这类命名为FileUpload.cs。这个新的类将负责两个关键功能:保存文件,并删除该文件。在下面的例子中,FileUpload类接收一个HttpPostedFile相应的变量,并将它保存到Web服务器上的特定点。另一个功能呢,相反,它接收到的文件的名称,并从Web服务器删除它。

译者:下边标红的代码是我加上去的。这样我们可以把图片和缩略图存到我们项目的文件夹下。否则他会存到:C:\Program Files\Common Files\Microsoft Shared\DevServer\10.0\目录下。

代码如下:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.IO;

namespace MvcApplication.Utils

{

    public static class FileUpload

    {

        public static char DirSeparator = Path.DirectorySeparatorChar;

        public static string FilesPath = HttpContext.Current.Server.MapPath(string.Format("Content{0}Uploads{1}", DirSeparator, DirSeparator));

 

        public static string UploadFile(HttpPostedFileBase file)

        {

            // Check if we have a file

            if (null == file) return "";

            // Make sure the file has content

            if (!(file.ContentLength > 0)) return "";

            string fileName = file.FileName;

            string fileExt = Path.GetExtension(file.FileName);

            // Make sure we were able to determine a proper

            // extension

            if (null == fileExt) return "";

            // Check if the directory we are saving to exists

            if (!Directory.Exists(FilesPath))

            {

                // If it doesn't exist, create the directory

                Directory.CreateDirectory(FilesPath);

            }

            // Set our full path for saving

            string path = FilesPath + DirSeparator + fileName;

            // Save our file

            file.SaveAs(Path.GetFullPath(path));

            // Return the filename

            return fileName;

        }

        public static void DeleteFile(string fileName)

        {

            // Don't do anything if there is no name

            if (fileName.Length == 0) return;

            // Set our full path for deleting

            string path = FilesPath + DirSeparator + fileName;

            // Check if our file exists

            if (File.Exists(Path.GetFullPath(path)))

            {

                // Delete our file

                File.Delete(Path.GetFullPath(path));

            }

        }

    }

}

这里面的类和功能被定义为静态,以避免在BooksController中创建类的实例。在类的顶部,创建一个常数定义

文件将被保存在哪,这应该是需要去更新保存在您的网站上不同的位置。在UploadFile功能中,如果上传的文件目录已经不存在,它将使用System.IO.Directory类中的CreateDirectory函数去创建一个目录。在删除功能

中也有一个类似的检查改文件是否存在,存在的话使用File.Delete功能删除。如果检查不执行,将返回一个错误,“试图删除一个不存在的文件。”

最后BooksController需要更新。在下面的例子中,三个重要的变化:

1。更新Createaction去调用UploadFile功能。

2。更新Edit action,首先调用DeleteFile,然后调用UploadFile。

3。 更新Delete确认功能,在从数据库删除这本书之前调用DeleteFile

using System;

using System.Collections.Generic;

using System.Data;

using System.Data.Entity;

using System.Linq;

using System.Web;

using System.Web.Mvc;

using MvcApplication.Models;

using PagedList;

using MvcApplication.Utils;

 

namespace MvcApplication.Controllers

{

    public class BookController : Controller

    {

        private BookDBContext db = new BookDBContext();

 

        //

        // GET: /Book/

 

        public ViewResult Index(string filter,int page = 1)

        {

            var books = from b in db.Books select b;

            #region Filter Switch

            switch (filter)

            {

                case "NewReleases":

                    var startDate = DateTime.Today.AddDays(-14);

                    books = books.Where(b => b.Published

                    <= DateTime.Today.Date

                    && b.Published >= startDate

                    );

                    break;

                case "ComingSoon":

                    books = books.Where(b => b.Published >

                    DateTime.Today.Date);

                    break;

                default:

                    // No filter needed

                    break;

            }

            ViewBag.CurrentFilter =

            String.IsNullOrEmpty(filter) ? "" : filter;

            #endregion

            books = books.OrderBy(b=>b.Author);

            const int maxRecords = 2;

            var currentPage = page <= 0 ? 1 : page;

            return View(books.ToPagedList(currentPage,

                                          maxRecords));

        }

 

        //

        // GET: /Book/Details/5

 

        public ViewResult Details(int id)

        {

            Book book = db.Books.Find(id);

            return View(book);

        }

 

        //

        // GET: /Book/Create

 

        public ActionResult Create()

        {

            return View();

        }

 

        //

        // POST: /Book/Create

 

        [HttpPost]

        public ActionResult Create(Book book,HttpPostedFileBase file)

        {

            if (ModelState.IsValid)

            {

                // Upload our file

                book.Thumbnail = FileUpload.UploadFile(file);

                db.Books.Add(book);

                db.SaveChanges();

                return RedirectToAction("Index");

            }

            return View(book);

 

        }

       

        //

        // GET: /Book/Edit/5

 

        public ActionResult Edit(int id)

        {

            Book book = db.Books.Find(id);

            return View(book);

        }

 

        //

        // POST: /Book/Edit/5

 

        [HttpPost]

        public ActionResult Edit(Book book, HttpPostedFileBase file)

        {

            if (ModelState.IsValid)

            {

                // Delete old file

                FileUpload.DeleteFile(book.Thumbnail);

                // Upload our file

                book.Thumbnail = FileUpload.UploadFile(file);

                db.Entry(book).State = EntityState.Modified;

                db.SaveChanges();

                return RedirectToAction("Index");

            }

            return View(book);

        }

 

        //

        // GET: /Book/Delete/5

 

        public ActionResult Delete(int id)

        {

            Book book = db.Books.Find(id);

            return View(book);

        }

 

        //

        // POST: /Book/Delete/5

 

        [HttpPost, ActionName("Delete")]

        public ActionResult DeleteConfirmed(int id)

        {

            Book book = db.Books.Find(id);

            // Delete old file

            FileUpload.DeleteFile(book.Thumbnail);

            db.Books.Remove(book);

            db.SaveChanges();

            return RedirectToAction("Index");

        }

 

        protected override void Dispose(bool disposing)

        {

            db.Dispose();

            base.Dispose(disposing);

        }

    }

}

  

 

另请参阅

aspx">HttpPostedFileBase  

 


 

  作者 技术弟弟
    发表评论
    请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
    用户名: 验证码:点击我更换图片
    最新评论 更多>>

    推荐热点

    • 浅析.NET下XML数据访问新机制
    • asp.net 面试+笔试题目第1/2页
    • C# 邮件地址是否合法的验证
    • asp.net 设置GridView的选中行的实现代码
    • C#高级编程:数据库连接[1]
    • 经典C++程序1
    • IIS 自动回收导致后台定时器失效的问题解决
    • ASP.NET&#160;GridView列表代码示例
    • Asp.net MVC源码分析--Action Filter的链式调用
    网站首页 - 友情链接 - 网站地图 - TAG标签 - RSS订阅 - 内容搜索
    Copyright © 2008-2015 计算机技术学习交流网. 版权所有

    豫ICP备11007008号-1