C#--图片上传(PC端和APP)保存及 跨域上传说明
手动跨域操作文件
补录:跨域访问文件夹文件是一种常见的需求,下面主要介绍的的通过代码使用具有权限账号的人来达到跨域操作文件的能力。
现在补充一下普通的一些需求场景,今天就遇到了一种需要经常需要登录远程服务器来部署文件的情况? 但是远程服务器限制了登录人数同时在线2人,每次我想发布新版本到测试服务器时都需要等别人断开连接后才可以。 那么学了这个知识后,我们就可以在我们本地就可以远程操作文件的删除,更新。
也很简单,下面的代码全不管,直接自己手动添加一个网络驱动器(驱动盘随机),填写上需要影射的服务器文件路径,勾选使用其他票据登陆,使用带有操作权限的账号就可以完整服务器文件夹影射到本地网络磁盘的需求了,这时我们就可以通过这个网络驱动器来进行想要的操作了,是不是很棒?!!!如下图:
我要影射的服务器路径为:\\10.0.9.244\Seagll2WebSite\WebApi\YuanXinApi\ 将该路径粘贴到文件夹输入框中即可。
通过代码跨域操作文件:
A-PC端:
1-页面--multiple是控制单张还是多张图片上传
<input id="BusRoute" type="file" class="btn btn-default btn-lg" style="height:34px;padding-top:5px;padding-bottom:5px;" multiple />
2-后台获取图片文件:
HttpFileCollection pcFileColl = HttpContext.Current.Request.Files;
3-保存示例:
#region 创建目录 //完整存储路径 string completeUrl = ""; //相对等级路径 string relativeUrl = ""; //string saveTempPath = "~/Resources/Pic"; //string picUploadPath = HttpContext.Current.Server.MapPath(saveTempPath); //添加根目录 completeUrl = @"\\10.0.8.52\YuanXinFiles\Office\"; ; //添加一级目录 string relativeOneUrl = DateTime.Now.Year.ToString(); completeUrl += "\\" + relativeOneUrl; relativeUrl += "\\" + relativeOneUrl; if (!Directory.Exists(completeUrl)) { Directory.CreateDirectory(completeUrl); } //添加二级目录 string relativeTwoUrl = DateTime.Now.Month.ToString(); completeUrl += "\\" + relativeTwoUrl; relativeUrl += "\\" + relativeTwoUrl; if (!Directory.Exists(completeUrl)) { Directory.CreateDirectory(completeUrl); } #endregion //保存 HttpFileCollection picColl = picModel.PcFileColl; for (var i = 0; i < picColl.Count; i++) { HttpPostedFile file = picColl[i]; //保存图片 //保存至指定目录 file.SaveAs(completeUrl + "\\" + fileName); }
B-APP:
前端页面长什么样不管了,后台拿到的是base64的字符串集合.
1-保存示例:
#region 创建目录 //完整存储路径 string completeUrl = ""; //相对等级路径 string relativeUrl = ""; //string saveTempPath = "~/Resources/Pic"; //string picUploadPath = HttpContext.Current.Server.MapPath(saveTempPath); //添加根目录 completeUrl = @"\\10.0.8.52\YuanXinFiles\Office\"; ; //添加一级目录 string relativeOneUrl = DateTime.Now.Year.ToString(); completeUrl += "\\" + relativeOneUrl; relativeUrl += "\\" + relativeOneUrl; if (!Directory.Exists(completeUrl)) { Directory.CreateDirectory(completeUrl); } //添加二级目录 string relativeTwoUrl = DateTime.Now.Month.ToString(); completeUrl += "\\" + relativeTwoUrl; relativeUrl += "\\" + relativeTwoUrl; if (!Directory.Exists(completeUrl)) { Directory.CreateDirectory(completeUrl); } #endregion //保存 byte[] bytes = Convert.FromBase64String(strPic.picCode); MemoryStream memStream = new MemoryStream(bytes); BinaryFormatter binFormatter = new BinaryFormatter(); System.Drawing.Bitmap map = new Bitmap(memStream); Image image = (Image)map; string imageName = Guid.NewGuid().ToString("N"); //保存图片 image.Save(completeUrl + "\\" + imageName + "." + strPic.picType); //保存图片
C-跨域保存问题:
跨域的常见场景如下图所示:我们通过电脑的网络影射,连接到所需要的目录,这里添加上拥有权限的人员账号即可访问目标文件夹,那么使用C#代码如何获得访问权限呢?
要获取以上访问权限,需要引用一个类和添加一些简单代码:
1-访问代码:
/// <summary> /// 通过指定用户执行上次图片操作 /// </summary> /// <param name="uploadAction"></param> public void UploadFileByUser(Action uploadAction) { //参考类:D:\SourceCode\MCSFramework\02.Develop\MobileWebApp\YuanXin\Services\FileUploadService\Controllers\UploadController.cs //无法通过权限认证--只能通过外网访问 try { var ip = "10.0.8.52"; var domain = "sinooceanland"; var username = ConfigurationManager.AppSettings["uploadUserName"].ToString(); //配置的用户名 var pwd = ConfigurationManager.AppSettings["uploadPassword"].ToString(); //配置的密码 var root = ConfigurationManager.AppSettings["uploadRootPath"].ToString(); //配置的文件根路径 using (NetworkShareAccesser.Access(ip, domain, username, pwd)) //建立连接 { uploadAction(); //图片保存代码 } } catch (System.Exception e) { } }
2-必须类:
public class NetworkShareAccesser : IDisposable { private string _remoteUncName; private string _remoteComputerName; public string RemoteComputerName { get { return this._remoteComputerName; } set { this._remoteComputerName = value; this._remoteUncName = @"\\" + this._remoteComputerName; } } public string UserName { get; set; } public string Password { get; set; } #region Consts private const int RESOURCE_CONNECTED = 0x00000001; private const int RESOURCE_GLOBALNET = 0x00000002; private const int RESOURCE_REMEMBERED = 0x00000003; private const int RESOURCETYPE_ANY = 0x00000000; private const int RESOURCETYPE_DISK = 0x00000001; private const int RESOURCETYPE_PRINT = 0x00000002; private const int RESOURCEDISPLAYTYPE_GENERIC = 0x00000000; private const int RESOURCEDISPLAYTYPE_DOMAIN = 0x00000001; private const int RESOURCEDISPLAYTYPE_SERVER = 0x00000002; private const int RESOURCEDISPLAYTYPE_SHARE = 0x00000003; private const int RESOURCEDISPLAYTYPE_FILE = 0x00000004; private const int RESOURCEDISPLAYTYPE_GROUP = 0x00000005; private const int RESOURCEUSAGE_CONNECTABLE = 0x00000001; private const int RESOURCEUSAGE_CONTAINER = 0x00000002; private const int CONNECT_INTERACTIVE = 0x00000008; private const int CONNECT_PROMPT = 0x00000010; private const int CONNECT_REDIRECT = 0x00000080; private const int CONNECT_UPDATE_PROFILE = 0x00000001; private const int CONNECT_COMMANDLINE = 0x00000800; private const int CONNECT_CMD_SAVECRED = 0x00001000; private const int CONNECT_LOCALDRIVE = 0x00000100; #endregion #region Errors private const int NO_ERROR = 0; private const int ERROR_ACCESS_DENIED = 5; private const int ERROR_ALREADY_ASSIGNED = 85; private const int ERROR_BAD_DEVICE = 1200; private const int ERROR_BAD_NET_NAME = 67; private const int ERROR_BAD_PROVIDER = 1204; private const int ERROR_CANCELLED = 1223; private const int ERROR_EXTENDED_ERROR = 1208; private const int ERROR_INVALID_ADDRESS = 487; private const int ERROR_INVALID_PARAMETER = 87; private const int ERROR_INVALID_PASSWORD = 1216; private const int ERROR_MORE_DATA = 234; private const int ERROR_NO_MORE_ITEMS = 259; private const int ERROR_NO_NET_OR_BAD_PATH = 1203; private const int ERROR_NO_NETWORK = 1222; private const int ERROR_BAD_PROFILE = 1206; private const int ERROR_CANNOT_OPEN_PROFILE = 1205; private const int ERROR_DEVICE_IN_USE = 2404; private const int ERROR_NOT_CONNECTED = 2250; private const int ERROR_OPEN_FILES = 2401; #endregion #region PInvoke Signatures [DllImport("Mpr.dll")] private static extern int WNetUseConnection( IntPtr hwndOwner, NETRESOURCE lpNetResource, string lpPassword, string lpUserID, int dwFlags, string lpAccessName, string lpBufferSize, string lpResult ); [DllImport("Mpr.dll")] private static extern int WNetCancelConnection2( string lpName, int dwFlags, bool fForce ); [StructLayout(LayoutKind.Sequential)] private class NETRESOURCE { public int dwScope = 0; public int dwType = 0; public int dwDisplayType = 0; public int dwUsage = 0; public string lpLocalName = ""; public string lpRemoteName = ""; public string lpComment = ""; public string lpProvider = ""; } #endregion /// <summary> /// Creates a NetworkShareAccesser for the given computer name. The user will be promted to enter credentials /// </summary> /// <param name="remoteComputerName"></param> /// <returns></returns> public static NetworkShareAccesser Access(string remoteComputerName) { return new NetworkShareAccesser(remoteComputerName); } /// <summary> /// Creates a NetworkShareAccesser for the given computer name using the given domain/computer name, username and password /// </summary> /// <param name="remoteComputerName"></param> /// <param name="domainOrComuterName"></param> /// <param name="userName"></param> /// <param name="password"></param> public static NetworkShareAccesser Access(string remoteComputerName, string domainOrComuterName, string userName, string password) { return new NetworkShareAccesser(remoteComputerName, domainOrComuterName + @"\" + userName, password); } /// <summary> /// Creates a NetworkShareAccesser for the given computer name using the given username (format: domainOrComputername\Username) and password /// </summary> /// <param name="remoteComputerName"></param> /// <param name="userName"></param> /// <param name="password"></param> public static NetworkShareAccesser Access(string remoteComputerName, string userName, string password) { return new NetworkShareAccesser(remoteComputerName, userName, password); } private NetworkShareAccesser(string remoteComputerName) { RemoteComputerName = remoteComputerName; this.ConnectToShare(this._remoteUncName, null, null, true); } private NetworkShareAccesser(string remoteComputerName, string userName, string password) { RemoteComputerName = remoteComputerName; UserName = userName; Password = password; this.ConnectToShare(this._remoteUncName, this.UserName, this.Password, false); } private void ConnectToShare(string remoteUnc, string username, string password, bool promptUser) { NETRESOURCE nr = new NETRESOURCE { dwType = RESOURCETYPE_DISK, lpRemoteName = remoteUnc }; int result; if (promptUser) { result = WNetUseConnection(IntPtr.Zero, nr, "", "", CONNECT_INTERACTIVE | CONNECT_PROMPT, null, null, null); } else { result = WNetUseConnection(IntPtr.Zero, nr, password, username, 0, null, null, null); } if (result != NO_ERROR) { throw new Win32Exception(result); } } private void DisconnectFromShare(string remoteUnc) { int result = WNetCancelConnection2(remoteUnc, CONNECT_UPDATE_PROFILE, false); if (result != NO_ERROR) { throw new Win32Exception(result); } } /// <summary> /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// </summary> /// <filterpriority>2</filterpriority> public void Dispose() { this.DisconnectFromShare(this._remoteUncName); } }
D--附件类展示(仅供参考):
/// <summary> /// 附件表 /// </summary> [ORTableMapping("office.Attachment")] public class AttachmentModel { /// <summary> /// 主键ID /// <summary> [ORFieldMapping("ID", PrimaryKey = true)] public string ID { get; set; } /// <summary> /// 资源ID /// <summary> [ORFieldMapping("ResourceID")] public string ResourceID { get; set; } /// <summary> /// 相对路径 /// <summary> [ORFieldMapping("RelativePath")] public string RelativePath { get; set; } /// <summary> /// 显示路径 /// </summary> public string ShowPath { get { string path = AttachmentModelAdapter.Instance.downLoadRootUrl + this.RelativePath + "/" + this.FileName + "." + this.FileType; return path; } } /// <summary> /// 文件名称 /// <summary> [ORFieldMapping("FileName")] public string FileName { get; set; } /// <summary> /// 文件类型 /// <summary> [ORFieldMapping("FileType")] public string FileType { get; set; } /// <summary> /// 创建时间 /// <summary> [ORFieldMapping("CreateTime")] public DateTime CreateTime { get; set; } /// <summary> /// 有效性 /// <summary> [ORFieldMapping("ValidStatus")] public bool ValidStatus { get; set; } } public class AttachmentModelCollection : EditableDataObjectCollectionBase<AttachmentModel> { } public class AttachmentModelAdapter : BaseAdapter<AttachmentModel, AttachmentModelCollection> { public static AttachmentModelAdapter Instance = new AttachmentModelAdapter(); private string ConnectionString = ConnectionNameDefine.YuanXinBusiness; //上传文件路径(如果路径含有相对路径标记~ 则使用Server获取完整路径,否则获取配置路径) public string upLoadRootUrl = ConfigurationManager.AppSettings["uploadRootPath"].Contains("~") ? HttpContext.Current.Server.MapPath(ConfigurationManager.AppSettings["uploadRootPath"]) : ConfigurationManager.AppSettings["uploadRootPath"]; //下载文件路径 public string downLoadRootUrl = ConfigurationManager.AppSettings["downLoadRootPath"]; //是否上传到本地服务器 public bool IsUploadLocalService = ConfigurationManager.AppSettings["IsUploadLocalService"] == "true" ? true : false; public AttachmentModelAdapter() { BaseConnectionStr = this.ConnectionString; } /// <summary> /// 设置用户权限通过远程文件增删 /// </summary> /// <param name="uploadAction"></param> private void UploadFileByUser(Action uploadAction) { //参考类:D:\SourceCode\MCSFramework\02.Develop\MobileWebApp\YuanXin\Services\FileUploadService\Controllers\UploadController.cs //无法通过权限认证--只能通过外网访问 try { if (IsUploadLocalService == false) { var ip = ConfigurationManager.AppSettings["uploadServiceIP"].ToString(); //上传的服务器IP--10.0.8.52 var domain = "sinooceanland"; var username = ConfigurationManager.AppSettings["uploadUserName"].ToString(); //配置的用户名--v-zhaotzh var pwd = ConfigurationManager.AppSettings["uploadPassword"].ToString(); //配置的密码--pass@123 var root = upLoadRootUrl; //配置的文件根路径--~/Resources/Pic using (NetworkShareAccesser.Access(ip, domain, username, pwd)) //建立连接 { uploadAction(); //图片保存代码 } } else { uploadAction(); //图片保存代码 } } catch (System.Exception e) { } } #region 文件保存 /// <summary> /// 保存附件集合 /// </summary> /// <returns></returns> private int SaveFileColl(AttachmentModelCollection acoll) { StringBuilder sql = new StringBuilder(); acoll.ForEach(ac => { sql.Append(ORMapping.GetInsertSql<AttachmentModel>(ac, TSqlBuilder.Instance, "") + ";"); }); int result = ViewBaseAdapter<AttachmentModel, List<AttachmentModel>>.Instance.RunSQLByTransaction(sql.ToString(), ConnectionNameDefine.YuanXinForDBHelp); return result; } /// <summary> /// 保存图片至服务器及将数据入库 /// </summary> /// <param name="picModel"></param> public void SavePicColl(PictureHelp picModel) { UploadFileByUser(() => { #region 创建目录 //完整存储路径 string completeUrl = ""; //相对等级路径 string relativeUrl = ""; //添加根目录 completeUrl = upLoadRootUrl; //添加一级目录 string relativeOneUrl = DateTime.Now.Year.ToString(); completeUrl += "\\" + relativeOneUrl; relativeUrl += "/" + relativeOneUrl; if (!Directory.Exists(completeUrl)) { Directory.CreateDirectory(completeUrl); } //添加二级目录 string relativeTwoUrl = DateTime.Now.Month.ToString(); completeUrl += "\\" + relativeTwoUrl; relativeUrl += "/" + relativeTwoUrl; if (!Directory.Exists(completeUrl)) { Directory.CreateDirectory(completeUrl); } #endregion AttachmentModelCollection modelColl = new AttachmentModelCollection(); #region 来源于APP if (picModel.AppPicColl != null && picModel.AppPicColl.Count > 0) { List<AppPicHelp> strPicColl = picModel.AppPicColl; foreach (var strPic in strPicColl) { byte[] bytes = Convert.FromBase64String(strPic.picCode); MemoryStream memStream = new MemoryStream(bytes); BinaryFormatter binFormatter = new BinaryFormatter(); System.Drawing.Bitmap map = new Bitmap(memStream); Image image = (Image)map; //保存图片 string imageName = Guid.NewGuid().ToString("N"); //图片重命名 image.Save(completeUrl + "\\" + imageName + "." + strPic.picType); //保存图片 AttachmentModel model = new AttachmentModel() { ID = Guid.NewGuid().ToString("N"), CreateTime = DateTime.Now, FileName = imageName, FileType = strPic.picType, RelativePath = relativeUrl, ResourceID = picModel.ResourceID, ValidStatus = true }; modelColl.Add(model); } } #endregion #region 来源于PC端 //来源于PC端 else if (picModel.PcFileColl != null && picModel.PcFileColl.Count > 0) { HttpFileCollection picColl = picModel.PcFileColl; //入库 for (var i = 0; i < picColl.Count; i++) { HttpPostedFile file = picColl[i]; string[] oldFileNameList = file.FileName.Split('.'); string fileName = oldFileNameList[0] + "_" + DateTime.Now.ToString("HH-mm-ss") + "_" + Guid.NewGuid().ToString("N").Substring(0, 5) + "." + oldFileNameList[1]; string[] newFileNameList = fileName.Split('.'); //保存图片 //保存至指定目录 file.SaveAs(completeUrl + "\\" + fileName); AttachmentModel model = new AttachmentModel { ID = System.Guid.NewGuid().ToString("N"), CreateTime = DateTime.Now, ValidStatus = true, FileName = newFileNameList[0], FileType = newFileNameList[1], RelativePath = relativeUrl, ResourceID = picModel.ResourceID }; modelColl.Add(model); } } #endregion //图片数据入库 AttachmentModelAdapter.Instance.SaveFileColl(modelColl); }); } #endregion /// <summary> /// 删除会议圈下图片文件及相关数据 /// </summary> /// <param name="momentID"></param> public void DelPicColl(string momentID) { AttachmentModelCollection coll = AttachmentModelAdapter.Instance.Load(m => m.AppendItem("ResourceID", momentID)); //删除本服务器图片 if (IsUploadLocalService == true) { coll.ForEach(c => { File.Delete(c.ShowPath); }); } //删除其他服务器图片 else { UploadFileByUser(() => { coll.ForEach(c => { File.Delete(c.ShowPath); }); }); } //删除数据 Delete(m => m.AppendItem("ResourceID", momentID)); } } #region 图片帮助类 public class PictureHelp { /// <summary> /// 资源ID /// </summary> public string ResourceID { get; set; } /// <summary> /// pc上传图片集合 /// </summary> public HttpFileCollection PcFileColl { get; set; } /// <summary> /// app上传图片集合 /// </summary> public List<AppPicHelp> AppPicColl { get; set; } } public class AppPicHelp { /// <summary> /// base64字节 /// </summary> public string picCode { get; set; } /// <summary> /// 图片类型(jpg/png/...) /// </summary> public string picType { get; set; } } #endregion
*博主的文章是自己平时开发总结的经验,由于博主的水平不高,不足和错误之处在所难免,希望大家能够批评指出。
*我的博客: http://www.cnblogs.com/lxhbky/