[WebApi] 搗鼓一個資源管理員--多檔案上傳,webapi搗鼓

來源:互聯網
上載者:User

[WebApi] 搗鼓一個資源管理員--多檔案上傳,webapi搗鼓

《打造一個網站或者其他網路應用的檔案管理介面(WebApi)第二章“多檔案上傳”》

========================================================
作者:qiujuer
部落格:blog.csdn.net/qiujuer
網站:www.qiujuer.net
開源庫:Genius-Android
轉載請註明出處:http://blog.csdn.net/qiujuer/article/details/41675299
========================================================

History

[WebApi] 搗鼓一個資源管理員--檔案下載


In This

既然訪問檔案介面有了,怎麼能少的了檔案的上傳介面呢!

既然是檔案上傳介面那就肯定要來一個猛一點的介面--多檔案上傳


CodeTime改動

進入正題前先來看看本次改動的檔案有哪些:



可以看見一共有4個檔案進行了改動,其中Home與ResourceApi是添加了方法,Model/Resource是新增,View/Upload也是新增。


Model部分

為了返回資料簡單方便,所以New 了一個類 Resource.cs

namespace WebResource.Models{    public class Resource    {        public string Id { get; set; }        public string Type { get; set; }    }}
If Easy?

ResourceApi 部分

然後來看看咱們的ResourceApi類:

namespace WebResource.Controllers{    [RoutePrefix("Resource")]    public class ResourceApiController : ApiController    {        private static readonly long MEMORY_SIZE = 64 * 1024 * 1024;        private static readonly string ROOT_PATH = HttpContext.Current.Server.MapPath("~/App_Data/");        [HttpGet]        [Route("{Id}")]        public async Task<HttpResponseMessage> Get(string Id)        {            // 進入時判斷當前請求中是否含有 ETag 標識,如果有就返回使用瀏覽器緩衝            // Return 304            var tag = Request.Headers.IfNoneMatch.FirstOrDefault();            if (Request.Headers.IfModifiedSince.HasValue && tag != null && tag.Tag.Length > 0)                return new HttpResponseMessage(HttpStatusCode.NotModified);            // 進行類比 App_Data/Image/{id}.png            // 開啟找到檔案            FileInfo info = new FileInfo(Path.Combine(ROOT_PATH, "Image", Id + ".png"));            if (!info.Exists)                return new HttpResponseMessage(HttpStatusCode.BadRequest);            FileStream file = null;            try            {                // 開啟檔案                file = new FileStream(info.FullName, FileMode.Open, FileAccess.Read, FileShare.Read);                HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);                // 在瀏覽器中顯示 inline                ContentDispositionHeaderValue disposition = new ContentDispositionHeaderValue("inline");                // 寫入檔案基本資料                disposition.FileName = file.Name;                disposition.Name = file.Name;                disposition.Size = file.Length;                // 判斷是否大於64Md,如果大於就採用分段流返回,否則直接返回                if (file.Length < MEMORY_SIZE)                {                    //Copy To Memory And Close.                    byte[] bytes = new byte[file.Length];                    await file.ReadAsync(bytes, 0, (int)file.Length);                    file.Close();                    MemoryStream ms = new MemoryStream(bytes);                    result.Content = new ByteArrayContent(ms.ToArray());                }                else                {                    result.Content = new StreamContent(file);                }                // 寫入檔案類型,這裡是圖片png                result.Content.Headers.ContentType = new MediaTypeHeaderValue("image/png");                result.Content.Headers.ContentDisposition = disposition;                // 設定緩衝資訊,該部分可以沒有,該部分主要是用於與開始部分結合以便瀏覽器使用304緩衝                // Set Cache                result.Content.Headers.Expires = new DateTimeOffset(DateTime.Now).AddHours(1);                // 這裡應該寫入檔案的儲存日期                result.Content.Headers.LastModified = new DateTimeOffset(DateTime.Now);                result.Headers.CacheControl = new CacheControlHeaderValue() { Public = true, MaxAge = TimeSpan.FromHours(1) };                // 設定Etag,這裡就簡單採用 Id                result.Headers.ETag = new EntityTagHeaderValue(string.Format("\"{0}\"", Id));                // 返回請求                return result;            }            catch            {                if (file != null)                {                    file.Close();                }            }            return new HttpResponseMessage(HttpStatusCode.BadRequest);        }        [HttpPost]        [Route("Upload")]        [ResponseType(typeof(Resource))]        public async Task<IHttpActionResult> Post()        {            List<Resource> resources = new List<Resource>();            // multipart/form-data            // 採用MultipartMemoryStreamProvider            var provider = new MultipartMemoryStreamProvider();            //讀取檔案資料            await Request.Content.ReadAsMultipartAsync(provider);            foreach (var item in provider.Contents)            {                // 判斷是否是檔案                if (item.Headers.ContentDisposition.FileName != null)                {                    //擷取到流                    var ms = item.ReadAsStreamAsync().Result;                    //進行流操作                    using (var br = new BinaryReader(ms))                    {                        if (ms.Length <= 0)                            break;                        //讀取檔案內容到記憶體中                        var data = br.ReadBytes((int)ms.Length);                        //Create                        //目前時間作為ID                        Resource resource = new Resource() { Id = DateTime.Now.ToString("yyyyMMddHHmmssffff", DateTimeFormatInfo.InvariantInfo) };                        //Info                        FileInfo info = new FileInfo(item.Headers.ContentDisposition.FileName.Replace("\"", ""));                        //檔案類型                        resource.Type = info.Extension.Substring(1).ToLower();                        //Write                        try                        {                            //檔案儲存體地址                            string dirPath = Path.Combine(ROOT_PATH);                            if (!Directory.Exists(dirPath))                            {                                Directory.CreateDirectory(dirPath);                            }                            File.WriteAllBytes(Path.Combine(dirPath, resource.Id), data);                            resources.Add(resource);                        }                        catch { }                    }                }            }            //返回            if (resources.Count == 0)                return BadRequest();            else if (resources.Count == 1)                return Ok(resources.FirstOrDefault());            else                return Ok(resources);        }    }}
與上一章比較看來,只是增加了一個方法 Post ,而後將其重新導向為Resource/Upload 

其中主要幹了些什麼我都在方法中註明了;應該是足夠簡單的。

現在運行一下,看看我們的Api是怎樣的:


下面我們來調用它試試。

HomeController部分

修改HomeController 添加一個Upload 方法:

namespace WebResource.Controllers{    public class HomeController : Controller    {        public ActionResult Index()        {            ViewBag.Title = "Home Page";            return View();        }        public ActionResult Upload()        {            return View();        }    }}

Upload.cshtml部分而後在方法上點擊右鍵添加視圖,然後進入View/Home/Upload.cshtml 視圖中修改為:

@{    ViewBag.Title = "Upload";}<h2>Upload</h2><div id="body">    <h1>多檔案上傳模式</h1>    <section class="main-content clear-fix">        <form name="form1" method="post" enctype="multipart/form-data" action="/Resource/Upload">            <fieldset>                <legend>File Upload Example</legend>                <div>                    <label for="caption">File1</label>                    <input name="file1" type="file" />                </div>                <div>                    <label for="image1">File2</label>                    <input name="file2" type="file" />                </div>                <div>                    <input type="submit" value="Submit" />                </div>            </fieldset>        </form>    </section></div>
在該視圖中,我們建立了一個 Form 表單,然後指定為 Post 模式;同時指定

enctype="multipart/form-data" action="/Resource/Upload"


RunTime

寫完了代碼當然是調試運行嘍!

運行 localhost:60586/Home/Upload
這裡我們添加檔案,還是使用上一章中的兩種圖片吧:


運行後:


當然,這裡是因為我的瀏覽器是Google瀏覽器,所以返回的是 XML 資料,如果你的事IE瀏覽器那麼應該返回的是Json 檔案。

WebApi會根據請求返回不同的資料。


可以看到,現在 App_Data檔案夾下,多了兩個檔案了;不過這兩個檔案是沒有加上檔案類型的;你可以手動給他加上個.png 然後開啟看看是不是那兩張圖片。


END

OK,這一章就到此為止了!

資源檔

第一章資源檔(說好了這章中添加)

第二章資源檔

下一章

下一章將會把上傳與下載查看兩個方法相互結合,搭配起來;同時將會結合資料進行輔助隱藏檔資訊。

同時,會講如何避免檔案重複上傳的問題。

========================================================
作者:qiujuer
部落格:blog.csdn.net/qiujuer
網站:www.qiujuer.net
開源庫:Genius-Android
轉載請註明出處:http://blog.csdn.net/qiujuer/article/details/41675299
========================================================


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.