WebAPI 笔记
一、基本配置
1. 全局配置 Global.asax
public class WebApiApplication : System.Web.HttpApplication { protected void Application_Start() { GlobalConfiguration.Configure(WebApiConfig.Register); GlobalConfiguration.Configuration.Filters.Add(new WebApiActionDebugFilter()); //配置返回的时间类型数据格式 GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.Converters.Add( new Newtonsoft.Json.Converters.IsoDateTimeConverter() { DateTimeFormat = "yyyy-MM-dd HH:mm:ss" } ); GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear(); } }
2. 日志记录 WebApiActionDebugFilter
public class WebApiActionDebugFilter : System.Web.Http.Filters.ActionFilterAttribute { /// <summary> /// 是否开启调试 /// </summary> private bool _isDebugLog = (ConfigurationManager.AppSettings["isDebugLog"]) != null && ConfigurationManager.AppSettings["isDebugLog"].ToString().ToLower() == "false" ? false : true; private readonly ILog txtlog = log4net.LogManager.GetLogger("txtLogger"); public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext context) { //log4net.Config.XmlConfigurator.ConfigureAndWatch(new System.IO.FileInfo(AppDomain.CurrentDomain.BaseDirectory + @"xmlconfig/log4net.config")); base.OnActionExecuting(context); if (_isDebugLog) { try { var controllerName = context.ControllerContext.ControllerDescriptor.ControllerName; var controller = context.ControllerContext.Controller.GetType(); var actionName = context.ActionDescriptor.ActionName; var descr = string.Empty; var members = controller.GetMethods(); foreach (var member in members) { if (member.Name == actionName)//如果是obejct { object[] attrs = member.GetCustomAttributes(typeof(System.ComponentModel.DescriptionAttribute), true); if (attrs.Length > 0) descr = (attrs[0] as System.ComponentModel.DescriptionAttribute).Description; break; } } var txtParams = ""; //******读流会影响图片上传的接口获取不到流了****** //var task = context.Request.Content.ReadAsStreamAsync(); //using (System.IO.Stream sm = task.Result) //{ // if (sm != null && sm.Length > 0) // { // sm.Seek(0, SeekOrigin.Begin); // int len = (int)sm.Length; // byte[] inputByts = new byte[len]; // sm.Read(inputByts, 0, len); // //sm.Close(); // txtParams = Encoding.UTF8.GetString(inputByts); // } //} if (context.Request.Method.ToString().ToLower() == "get") { txtParams = context.Request.RequestUri.Query; } else if (context.Request.Method.ToString().ToLower() == "post") { if (context.ActionArguments != null && context.ActionArguments.Count > 0) { txtParams = JsonConvert.SerializeObject(context.ActionArguments); } } var beginRequestTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"); context.Request.Content.Headers.Add("BeginRequestTime", beginRequestTime); //写文件 var logInfo = new { CallTime = beginRequestTime, ActionType = "请求", ControllerName = controllerName, ActionName = actionName, Description = descr, Params = txtParams, ReqGuid = context.Request.GetCorrelationId().ToString().Replace("-", "") }; Console.WriteLine(logInfo); Util.ExecuteInvoke(() => txtlog.Info(GetObjetJson(logInfo))); } catch (Exception ex) { var response = new HttpResponseMessage(HttpStatusCode.BadRequest) { Content = new StringContent("请求出错,详细信息如下:"+Environment.NewLine+ex.Message), ReasonPhrase = "请求不被允许" }; throw new HttpResponseException(response); //txtlog.Info("请求出错"+ ex.Message + ex.StackTrace); } } } public override void OnActionExecuted(System.Web.Http.Filters.HttpActionExecutedContext context) { base.OnActionExecuted(context); if (_isDebugLog) { try { var controllerName = context.ActionContext.ControllerContext.ControllerDescriptor.ControllerName; var actionName = context.ActionContext.ActionDescriptor.ActionName; var txtResult = context.Response.Content.ReadAsStringAsync().Result; var endTime = DateTime.Now; var reqGuid = context.ActionContext.Request.GetCorrelationId().ToString().Replace("-", ""); var beginTime = context.Request.Content.Headers.GetValues("BeginRequestTime").FirstOrDefault(); var execTime = Util.ExecTimeDiff(Convert.ToDateTime(beginTime), endTime); //写文件 var logInfo = new { CallTime = endTime.ToString("yyyy-MM-dd HH:mm:ss.fff"), ExecTime = execTime, ActionType = "响应", ControllerName = controllerName, ActionName = actionName, Params = txtResult, ReqGuid = reqGuid }; Util.ExecuteInvoke(() => txtlog.Info(GetObjetJson(logInfo))); } catch (Exception ex) { txtlog.Info("响应出错" + ex.Message + ex.StackTrace); } } } private string GetObjetJson(object message) { var retStr = ""; try { if (message != null) { var json = JsonConvert.SerializeObject(message); retStr = json; //if (json != null) retStr = json.Replace("\\\"", ""); } } catch (Exception) { // ignored } return retStr; } }
3. 文件上传
public class SysUpdateController : ApiController { [HttpGet] [ActionName("getfilemd5")] public HttpResponseMessage GetFileMD5(string fileName, string parentDir) { HttpResponseMessage response = new HttpResponseMessage(); try { string baseDirectory = Path.Combine(System.Web.Hosting.HostingEnvironment.MapPath("~/"), string.Format("{0}\\", parentDir)); fileName = Path.Combine(baseDirectory, fileName); string content = ""; if (!File.Exists(fileName)) { content = "未知错误"; } else { content = GetMD5HashFromFile(fileName); } response.Content = new StringContent(content, System.Text.Encoding.UTF8, "text/json"); response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); } catch (Exception ex) { response.Content = new StringContent("未知错误:" + ex.Message, System.Text.Encoding.UTF8, "text/json"); response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); } return response; } [HttpGet] [ActionName("getpackage")] public HttpResponseMessage GetPackage() { HttpResponseMessage response = new HttpResponseMessage(); try { string baseDirectory = System.Web.Hosting.HostingEnvironment.MapPath("~/"); string filePath = Path.Combine(baseDirectory, "QCPackage\\"); string[] files = Directory.GetFiles(filePath); if (files.Length > 0) { filePath = files[0]; FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read); response.Content = new StreamContent(fileStream); response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment"); response.Content.Headers.ContentDisposition.FileName = Path.GetFileName(filePath); // 这句话要告诉浏览器要下载文件 response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); response.Content.Headers.ContentLength = new FileInfo(filePath).Length; } else { response.Content = new StringContent("未知错误", System.Text.Encoding.UTF8, "text/json"); response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); } } catch { response.Content = new StringContent("未知错误", System.Text.Encoding.UTF8, "text/json"); response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); } return response; } /// <summary> /// 文件下载 /// </summary> /// <param name="filePath "></param> /// <returns></returns> [HttpGet] [ActionName("getfiles")] public HttpResponseMessage GetFiles(string parentDir) { HttpResponseMessage response = new HttpResponseMessage(); try { List<string> files = new List<string>(); string baseDirectory = Path.Combine(System.Web.Hosting.HostingEnvironment.MapPath("~/"), string.Format("{0}\\", parentDir)); string[] rootPathFiles = Directory.GetFiles(baseDirectory); files.AddRange(rootPathFiles); string[] rootPathDirectories = Directory.GetDirectories(baseDirectory); foreach (string directory in rootPathDirectories) { GetFiles(directory, files); } for (int i = 0; i < files.Count; i++) { files[i] = System.Text.Encoding.UTF8.GetString(System.Text.Encoding.UTF8.GetBytes(files[i].Replace(baseDirectory, ""))); } string content = Newtonsoft.Json.JsonConvert.SerializeObject(files); response.Content = new StringContent(content, System.Text.Encoding.UTF8, "text/json"); response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); } catch { response.Content = new StringContent("未知错误", System.Text.Encoding.UTF8, "text/json"); response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); } return response; } /// <summary> /// 文件下载 /// </summary> /// <param name="filePath "></param> /// <returns></returns> [HttpGet] [ActionName("upgrade")] public HttpResponseMessage Upgrade(string fileName, string parentDir) { string baseDirectory = Path.Combine(System.Web.Hosting.HostingEnvironment.MapPath("~/"), string.Format("{0}\\", parentDir)); string filePath = Path.Combine(baseDirectory, fileName); FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read); HttpResponseMessage response = new HttpResponseMessage(); response.Content = new StreamContent(fileStream); response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment"); response.Content.Headers.ContentDisposition.FileName = Path.GetFileName(filePath); // 这句话要告诉浏览器要下载文件 response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); response.Content.Headers.ContentLength = new FileInfo(filePath).Length; return response; } private void GetFiles(string filePath, List<string> files) { string[] currentPathFiles = Directory.GetFiles(filePath); string[] currentPathDirectories = Directory.GetDirectories(filePath); files.AddRange(currentPathFiles); foreach (string currentPath in currentPathDirectories) { GetFiles(currentPath, files); } } private string GetMD5HashFromFile(string fileName) { try { FileStream file = new FileStream(fileName, FileMode.Open); System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider(); byte[] retVal = md5.ComputeHash(file); file.Close(); StringBuilder sb = new StringBuilder(); for (int i = 0; i < retVal.Length; i++) { sb.Append(retVal[i].ToString("x2")); } return sb.ToString(); } catch (Exception ex) { throw ex; } } }
4. FTPHelper
public class FTPHelper { /// <summary> /// FTP请求对象 /// </summary> FtpWebRequest request = null; /// <summary> /// FTP响应对象 /// </summary> FtpWebResponse response = null; /// <summary> /// FTP服务器地址 /// </summary> public string ftpURI { get; private set; } /// <summary> /// FTP服务器IP /// </summary> public string ftpServerIP { get; private set; } /// <summary> /// FTP服务器默认目录 /// </summary> public string ftpRemotePath { get; private set; } /// <summary> /// FTP服务器登录用户名 /// </summary> public string ftpUserID { get; private set; } /// <summary> /// FTP服务器登录密码 /// </summary> public string ftpPassword { get; private set; } /// <summary> /// 初始化 /// </summary> /// <param name="FtpServerIP">FTP连接地址</param> /// <param name="FtpRemotePath">指定FTP连接成功后的当前目录, 如果不指定即默认为根目录</param> /// <param name="FtpUserID">用户名</param> /// <param name="FtpPassword">密码</param> public FTPHelper(string ftpServerIP, string ftpRemotePath, string ftpUserID, string ftpPassword) { this.ftpServerIP = ftpServerIP; this.ftpRemotePath = ftpRemotePath; this.ftpUserID = ftpUserID; this.ftpPassword = ftpPassword; this.ftpURI = "ftp://" + ftpServerIP + "/" + ftpRemotePath + "/"; } ~FTPHelper() { if (response != null) { response.Close(); response = null; } if (request != null) { request.Abort(); request = null; } } /// <summary> /// 建立FTP链接,返回响应对象 /// </summary> /// <param name="uri">FTP地址</param> /// <param name="ftpMethod">操作命令</param> /// <returns></returns> private FtpWebResponse Open(Uri uri, string ftpMethod) { request = (FtpWebRequest)FtpWebRequest.Create(uri); request.Method = ftpMethod; request.UseBinary = true; request.KeepAlive = false; //request.UsePassive = false;//主动模式 request.Credentials = new NetworkCredential(this.ftpUserID, this.ftpPassword); return (FtpWebResponse)request.GetResponse(); } /// <summary> /// 建立FTP链接,返回请求对象 /// </summary> /// <param name="uri">FTP地址</param> /// <param name="ftpMethod">操作命令</param> private FtpWebRequest OpenRequest(Uri uri, string ftpMethod) { request = (FtpWebRequest)WebRequest.Create(uri); request.Method = ftpMethod; request.UseBinary = true; request.KeepAlive = false; request.Credentials = new NetworkCredential(this.ftpUserID, this.ftpPassword); return request; } /// <summary> /// 创建目录 /// </summary> /// <param name="remoteDirectoryName">目录名</param> public void CreateDirectory(string remoteDirectoryName) { response = Open(new Uri(ftpURI + remoteDirectoryName), WebRequestMethods.Ftp.MakeDirectory); } /// <summary> /// 更改目录或文件名 /// </summary> /// <param name="currentName">当前名称</param> /// <param name="newName">修改后新名称</param> public void ReName(string currentName, string newName) { request = OpenRequest(new Uri(ftpURI + currentName), WebRequestMethods.Ftp.Rename); request.RenameTo = newName; response = (FtpWebResponse)request.GetResponse(); } /// <summary> /// 切换当前目录 /// </summary> /// <param name="IsRoot">true:绝对路径 false:相对路径</param> public void GotoDirectory(string DirectoryName, bool IsRoot) { if (IsRoot) ftpRemotePath = DirectoryName; else ftpRemotePath += "/" + DirectoryName; ftpURI = "ftp://" + ftpServerIP + "/" + ftpRemotePath + "/"; } /// <summary> /// 删除目录(包括下面所有子目录和子文件) /// </summary> /// <param name="remoteDirectoryName">要删除的带路径目录名:如web/test</param> /* * 例:删除test目录 FTPHelper helper = new FTPHelper("x.x.x.x", "web", "user", "password"); helper.RemoveDirectory("web/test"); */ public void RemoveDirectory(string remoteDirectoryName) { GotoDirectory(remoteDirectoryName, true); var listAll = ListFilesAndDirectories(); foreach (var m in listAll) { if (m.IsDirectory) RemoveDirectory(m.Path); else DeleteFile(m.Name); } GotoDirectory(remoteDirectoryName, true); response = Open(new Uri(ftpURI), WebRequestMethods.Ftp.RemoveDirectory); } /// <summary> /// 文件上传 /// </summary> /// <param name="localFilePath">本地文件路径</param> public void Upload(string localFilePath) { FileInfo fileInf = new FileInfo(localFilePath); request = OpenRequest(new Uri(ftpURI + fileInf.Name), WebRequestMethods.Ftp.UploadFile); request.ContentLength = fileInf.Length; int buffLength = 2048; byte[] buff = new byte[buffLength]; int contentLen; using (var fs = fileInf.OpenRead()) { using (var strm = request.GetRequestStream()) { contentLen = fs.Read(buff, 0, buffLength); while (contentLen != 0) { strm.Write(buff, 0, contentLen); contentLen = fs.Read(buff, 0, buffLength); } } } } public string Upload(byte[] buff) { string fileName = DateTime.Now.ToFileTime().ToString() + ".png"; string path = DateTime.Now.ToString("yyyyMM").ToString(); if (!IsExist(path)) CreateDirectory(path); path += "/" + fileName; request = OpenRequest(new Uri(ftpURI + path), WebRequestMethods.Ftp.UploadFile); using (var strm = request.GetRequestStream()) { strm.Write(buff, 0, buff.Length); } return path; } /// <summary> /// 上传best64图片 /// </summary> /// <param name="base64String"></param> /// <returns></returns> public string UploadBase64(string base64String) { string fileName = DateTime.Now.ToFileTime().ToString() + ".png"; string path = DateTime.Now.ToString("yyyyMM").ToString(); if (!IsExist(path)) CreateDirectory(path); path += "/" + fileName; request = OpenRequest(new Uri(ftpURI + path), WebRequestMethods.Ftp.UploadFile); request.ContentLength = base64String.Length; byte[] byteArray = Convert.FromBase64String(base64String); using (var strm = request.GetRequestStream()) { strm.Write(byteArray, 0, byteArray.Length); } return path; } /// <summary> /// 下载 /// </summary> /// <param name="saveFilePath">下载后的保存路径</param> /// <param name="downloadFileName">要下载的文件名</param> public void Download(string saveFilePath, string downloadFileName) { using (FileStream outputStream = new FileStream(saveFilePath + "\\" + downloadFileName, FileMode.Create)) { response = Open(new Uri(ftpURI + downloadFileName), WebRequestMethods.Ftp.DownloadFile); using (Stream ftpStream = response.GetResponseStream()) { long cl = response.ContentLength; int bufferSize = 2048; int readCount; byte[] buffer = new byte[bufferSize]; readCount = ftpStream.Read(buffer, 0, bufferSize); while (readCount > 0) { outputStream.Write(buffer, 0, readCount); readCount = ftpStream.Read(buffer, 0, bufferSize); } } } } /// <summary> /// 获取文件best64编码 /// </summary> /// <param name="downloadFileName"></param> /// <returns></returns> public string DownloadBest64(string downloadFileName) { response = Open(new Uri(ftpURI + downloadFileName), WebRequestMethods.Ftp.DownloadFile); var ftpStream = response.GetResponseStream(); var ms = new MemoryStream(); var bufferSize = 1024; var buffer = new byte[bufferSize]; while ((bufferSize = ftpStream.Read(buffer, 0, bufferSize)) > 0) { ms.Write(buffer, 0, bufferSize); } var bast64 = Convert.ToBase64String(ms.ToArray()); return bast64; } /// <summary> /// 删除文件 /// </summary> /// <param name="remoteFileName">要删除的文件名</param> public void DeleteFile(string remoteFileName) { response = Open(new Uri(ftpURI + remoteFileName), WebRequestMethods.Ftp.DeleteFile); } /// <summary> /// 获取当前目录的文件和一级子目录信息 /// </summary> /// <returns></returns> public List<FileStruct> ListFilesAndDirectories() { var fileList = new List<FileStruct>(); response = Open(new Uri(ftpURI), WebRequestMethods.Ftp.ListDirectoryDetails); using (var stream = response.GetResponseStream()) { using (var sr = new StreamReader(stream)) { string line = null; while ((line = sr.ReadLine()) != null) { //line的格式如下: //08-18-13 11:05PM <DIR> aspnet_client //09-22-13 11:39PM 2946 Default.aspx DateTime dtDate = DateTime.ParseExact(line.Substring(0, 8), "MM-dd-yy", null); DateTime dtDateTime = DateTime.Parse(dtDate.ToString("yyyy-MM-dd") + line.Substring(8, 9)); string[] arrs = line.Split(' '); var model = new FileStruct() { IsDirectory = line.IndexOf("<DIR>") > 0 ? true : false, CreateTime = dtDateTime, Name = arrs[arrs.Length - 1], Path = ftpRemotePath + "/" + arrs[arrs.Length - 1] }; fileList.Add(model); } } } return fileList; } /// <summary> /// 列出当前目录的所有文件 /// </summary> public List<FileStruct> ListFiles() { var listAll = ListFilesAndDirectories(); var listFile = listAll.Where(m => m.IsDirectory == false).ToList(); return listFile; } /// <summary> /// 列出当前目录的所有一级子目录 /// </summary> public List<FileStruct> ListDirectories() { var listAll = ListFilesAndDirectories(); var listFile = listAll.Where(m => m.IsDirectory == true).ToList(); return listFile; } /// <summary> /// 判断当前目录下指定的子目录或文件是否存在 /// </summary> /// <param name="remoteName">指定的目录或文件名</param> public bool IsExist(string remoteName) { var list = ListFilesAndDirectories(); if (list.Count(m => m.Name == remoteName) > 0) return true; return false; } /// <summary> /// 判断当前目录下指定的一级子目录是否存在 /// </summary> /// <param name="RemoteDirectoryName">指定的目录名</param> public bool IsDirectoryExist(string remoteDirectoryName) { var listDir = ListDirectories(); if (listDir.Count(m => m.Name == remoteDirectoryName) > 0) return true; return false; } /// <summary> /// 判断当前目录下指定的子文件是否存在 /// </summary> /// <param name="RemoteFileName">远程文件名</param> public bool IsFileExist(string remoteFileName) { var listFile = ListFiles(); if (listFile.Count(m => m.Name == remoteFileName) > 0) return true; return false; } }
从文件流读取
var paths = string.Empty; var streamProvider = new MultipartMemoryStreamProvider(); //var dic = new Dictionary<string, string>(); await Request.Content.ReadAsMultipartAsync(streamProvider).ContinueWith(multipartContent => { if (multipartContent.IsFaulted || multipartContent.IsCanceled) return; foreach (var content in multipartContent.Result.Contents) { if (content.Headers.ContentType == null || content.Headers.ContentType.MediaType == null || !content.Headers.ContentType.MediaType.Contains("image")) //if (string.IsNullOrEmpty(content.Headers.ContentDisposition.FileName)) { //var val = content.ReadAsStringAsync().Result; //dic.Add(content.Headers.ContentDisposition.Name.Replace("\"", ""), val); } else { var bytes = content.ReadAsByteArrayAsync().Result; var path = ftp.Upload(bytes); paths += path + ","; } } });