手動跨域操作文件
補錄:跨域訪問文件夾文件是一種常見的需求,下面主要介紹的的通過代碼使用具有權限賬號的人來達到跨域操作文件的能力。
現在補充一下普通的一些需求場景,今天就遇到了一種需要經常需要登錄遠程服務器來部署文件的情況? 但是遠程服務器限制了登錄人數同時在線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