最近公司的系统约来越多,基本上每个系统都需要用到“资源”,以前只是简单的把“资源”放到Web服务器中,但是这样的话有一个头痛的问题----如何去管理“资源”?
现在不是很流行API嘛,大家好像都在整什么面向服务、面向资源、RESTful什么的,据说在与复杂性的斗争中,人们讨论表象化状态转移(REST)已成为了一种时尚!我对这些概念也就是知道个大概,但是也不能解释的很清楚,但是用意和优点还是很明确的!说白了就是各式各样的“API”,可能我的理解有偏差,还望大家海涵,哈哈!
HTTP中有几个常见谓词,分别是GET/POST/PUT/DELETE,这也正是对应了我们经常说到的CRUD,含义就是对一个资源的增删改查!
那咱能不能来一个文件API呢?实现对一个一个文件的CRUD?
既然有了想法,咱就得开始干了!那么接下来的问题又来了,怎么干?
文件的增删改查很简单,基本功呗!
数据格式?字节数组吧,不用转来转去,
数据传输呢?就跟一般的API一样走HTTP协议,HTTP请求报文中分为两个部分:请求头和请求体,既然这样,正好符合我们的需求,请求体承载文件流的字节数组,请求头中附加一些额外的信息!
说到这,基本上大概的“形状”就有了!那咱就开始干!!!
添加一个Web应用程序作为服务端,WebForms或者Mvc的都可以。我这里演示的是Mvc的!
不废话,先上代码(只有上传操作),待会大概解释一下。
// ***********************************************************************// PRoject : Beimu.Bfs// Assembly : Beimu.Bfs.Web// Author : iceStone// Created : 2014年01月03日 10:23//// Last Modified By : iceStone// Last Modified On : 2014年01月03日 10:23// ***********************************************************************// <copyright file="DefaultController.cs" company="Wedn.Net">// Copyright (c) Wedn.Net. All rights reserved.// </copyright>// <summary></summary>// ***********************************************************************using System;using System.Collections;using System.Collections.Generic;using System.IO;using System.Linq;using System.Security.Cryptography;using System.Web;using System.Web.Mvc;using Beimu.Bfs.Web.Utilities;namespace Beimu.Bfs.Web.Controllers{ /// <summary> /// 默认控制器. /// </summary> /// <remarks> /// 2014年01月03日 10:23 Created By iceStone /// </remarks> public class DefaultController : Controller { /// <summary> /// 身份验证 /// </summary> /// <param name="filterContext"></param> protected override void OnActionExecuting(ActionExecutingContext filterContext) { var uid = Request.Headers["bfs-uid"];// Request["uid"]; var pwd = Request.Headers["bfs-pwd"];//Request["pwd"]; if (!(string.IsNullOrEmpty(uid) || string.IsNullOrEmpty(pwd))) { var user = new Users(); if (!user.Exist(uid) || user[uid] != pwd) { filterContext.Result = Json(new { Status = 400, Message = "用户名或密码不正确" }); return; } } base.OnActionExecuting(filterContext); } /// <summary> /// 上传操作. /// </summary> /// <remarks> /// 2014年01月03日 10:23 Created By iceStone /// </remarks> /// <returns>ActionResult.</returns> public ActionResult Upload() { #region 批量 //var files = Request.Files; //if (files == null || files.Count == 0) return Json(new { Status = 101, Message = "" }); //var dict = new Dictionary<int, string>(); //int index = -1; //foreach (HttpPostedFile file in files) //{ // index++; // if (file == null || file.ContentLength == 0) continue; // var ext = Path.GetExtension(file.FileName); // if (!Config.UploadAllowType.Contains(ext)) continue; // if (file.ContentLength >= (Config.UploadMaxSize * 1024 * 1024)) continue; // string root = AppDomain.CurrentDomain.BaseDirectory; // string path = string.Format("{0}/{1}/{2}/{3}", Config.UploadRoot, dir, DateTime.Now.ToString("yyyy"), DateTime.Now.ToString("MM")); // string filename = GetStreammd5(file.InputStream) + ext;//Path.GetFileName(file.FileName); // file.SaveAs(Path.Combine(root, path, filename)); // dict.Add(index, Config.SiteUrl + path + filename); //} //return Json(dict); #endregion string ext = Request.Headers.AllKeys.Contains("bfs-ext") ? Request.Headers["bfs-ext"] : ".jpg"; var dir = Request.Headers.AllKeys.Contains("bfs-dir") ? Request.Headers["bfs-dir"] : Request.Headers["bfs-uid"]; //dir = string.IsNullOrEmpty(dir) ? "common" : dir; using (var stream = Request.InputStream) { //var files = Request.Files; if (stream.Length == 0) return SetHeaders(104, "上传文件为空"); if (stream.Length >= (Config.UploadMaxSize * 1024 * 1024)) return SetHeaders(101, "上传文件过大"); //string root = AppDomain.CurrentDomain.BaseDirectory; string path = string.Format("/{0}/{1}/{2}/{3}/", Config.UploadRoot, dir, DateTime.Now.ToString("yyyy"), DateTime.Now.ToString("MM")); string filename = GetStreamMd5(stream) + ext;//Path.GetFileName(file.FileName); string fullPath = Server.MapPath(path); if (!Directory.Exists(fullPath)) Directory.CreateDirectory(fullPath); //var buffer = new byte[stream.Length]; //stream.Read(buffer, 0, buffer.Length); //将流的内容读到缓冲区 //using (var fs = new FileStream(fullPath + filename, FileMode.CreateNew, Fileaccess.Write)) //{ // fs.Write(buffer, 0, buffer.Length); // fs.Flush(); // //fs.Close(); //} //using (var reader=new StreamReader(stream)) //{ // using (var writer = new StreamWriter(fullPath + filename, false)) // { // writer.Write(reader.ReadToEnd()); // writer.Flush(); // } //} using (var fs = new FileStream(fullPath + filename, FileMode.Create)) { byte[] bytes = new byte[stream.Length]; int numBytesRead = 0; int numBytesToRead = (int)stream.Length; stream.Position = 0; while (numBytesToRead > 0) { int n = stream.Read(bytes, numBytesRead, Math.Min(numBytesToRead, int.MaxValue)); if (n <= 0) break; fs.Write(bytes, numBytesRead, n); numBytesRead += n; numBytesToRead -= n; } fs.Close(); } return SetHeaders(100, Config.SiteUrl + path + filename); } //if (file == null || file.ContentLength == 0) return SetHeaders(103, "上传文件为空"); //var ext = Path.GetExtension(file.FileName); //if (!Config.UploadAllowType.Contains(ext)) return SetHeaders(102, "上传非法文件"); //if (file.ContentLength >= (Config.UploadMaxSize * 1024 * 1024)) return SetHeaders(101, "上传文件过大"); //string root = AppDomain.CurrentDomain.BaseDirectory; //string path = string.Format("{0}/{1}/{2}/{3}", Config.UploadRoot, dir, DateTime.Now.ToString("yyyy"), DateTime.Now.ToString("MM")); //string filename = GetStreamMd5(file.InputStream) + ext;//Path.GetFileName(file.FileName); //string fullPath = Path.Combine(root, path); //if (!Directory.Exists(fullPath)) // Directory.CreateDirectory(fullPath); //file.SaveAs(Path.Combine(root, path, filename)); //return SetHeaders(100, Config.SiteUrl + path + filename); } [NonAction] public ContentResult SetHeaders(int status, string resault) { Response.Headers.Add("bfs-status", status.ToString()); Response.Headers.Add("bfs-result", resault); return Content(string.Empty); } /// <summary> /// 获取文件的MD5值 /// </summary> /// <remarks> /// 2013年11月28日 19:24 Created By 汪磊 /// </remarks> /// <param name="stream">文件流</param>
新闻热点
疑难解答