Many of my friends may encounter such a requirement when working on a web project:
When uploading files, you need to save the uploaded files to another dedicated file server.
To implement such a function, there are two solutions:
Solution 1: Create a new site on the file server to receive and save uploaded files.
Solution 2: Share the specified directory of the file server with the Web server to save the file.
Solution 1 Needless to say, it should be very simple. Just point the action attribute of the Form of the uploaded file to the site on the file server. Let's focus on solution 2.
You may say that solution 2 is also very simple. You just need to perform disk ing on the Web server and then directly access it. This is not the case. The default IIS account is network_service. This account has no permission to access the shared directory. Therefore, when you deploy the site on IIS, when you access the ing disk, the error "The path cannot be found" is reported. Therefore, directly creating a disk ing does not work. We need to create a ing with the specified account in the program and run the IIS process with this account. The following describes the detailed steps and related code.
1. Create a shared directory on the file server and an access account.
For example, the shared directory is: // 192.168.0.9/share
User-1 Password: 123456
2. Create a user on the Web server: User-1 Password: 123456. Select the default user group for the user group.
3. Create a common wnethelper in a web project
Using system. runtime. interopservices; public class wnethelper {[dllimport ("records. DLL ", entrypoint =" wnetaddconnection2 ")] Private Static extern uint wnetaddconnection2 (netresource lpnetresource, string lppassword, string lpusername, uint dwflags); [dllimport (" MIP. DLL ", entrypoint =" wnetcancelconnection2 ")] Private Static extern uint wnetcancelconnection2 (string lpname, uint dwflags, bool Fforce); [structlayout (layoutkind. sequential)] public class netresource {public int dwscope; Public int dwtype; Public int dwdisplaytype; Public int dwusage; Public String lplocalname; Public String lpremotename; Public String lpcomment; Public String lpprovider ;} /// <summary> /// perform local ing for network sharing /// </Summary> /// <Param name = "username"> access user name (for Windows systems, add computer Name, such as: comp-1/user-1) </param> /// <Param name = "password"> access user password </param> /// <Param name = "remotename"> network sharing path (for example: // 192.168.0.9/share) </param> /// <Param name = "localname"> Local ing drive letter </param> /// <returns> </returns> Public static uint wnetaddconnection (string username, string password, string remotename, string localname) {netresource = new netresource (); netresource. dwscope = 2; netresource. dwtype = 1; netresource. dwdisplaytype = 3; netresource. dwusage = 1; netresource. lplocalname = localname; netresource. lpremotename = remotename. trimend ('//'); uint result = wnetaddconnection2 (netresource, password, username, 0); return result;} public static uint wnetcancelconnection (string name, uint flags, bool force) {uint nret = wnetcancelconnection2 (name, flags, force); Return nret ;}}
4. Specify the account user-1 for IIS
There are two ways to implement this function:
A) on the web. <system. web> Add the following configuration under the node: <identity impersonate = "true" username = "user-1" Password = "123456"/>
B) add a public class logonimpersonate TO THE WEB Project.
public class LogonImpersonate : IDisposable{ static public string DefaultDomain { get { return "."; } } const int LOGON32_LOGON_INTERACTIVE = 2; const int LOGON32_PROVIDER_DEFAULT = 0; [System.Runtime.InteropServices.DllImport("Kernel32.dll")] extern static int FormatMessage(int flag, ref IntPtr source, int msgid, int langid, ref string buf, int size, ref IntPtr args); [System.Runtime.InteropServices.DllImport("Kernel32.dll")] extern static bool CloseHandle(IntPtr handle); [System.Runtime.InteropServices.DllImport("Advapi32.dll", SetLastError = true)] extern static bool LogonUser( string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken ); IntPtr token; System.Security.Principal.WindowsImpersonationContext context; public LogonImpersonate(string username, string password) { if (username.IndexOf("//") == -1) { Init(username, password, DefaultDomain); } else { string[] pair = username.Split(new char[] { '//' }, 2); Init(pair[1], password, pair[0]); } } public LogonImpersonate(string username, string password, string domain) { Init(username, password, domain); } void Init(string username, string password, string domain) { if (LogonUser(username, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token)) { bool error = true; try { context = System.Security.Principal.WindowsIdentity.Impersonate(token); error = false; } finally { if (error) CloseHandle(token); } } else { int err = System.Runtime.InteropServices.Marshal.GetLastWin32Error(); IntPtr tempptr = IntPtr.Zero; string msg = null; FormatMessage(0x1300, ref tempptr, err, 0, ref msg, 255, ref tempptr); throw (new Exception(msg)); } } ~LogonImpersonate() { Dispose(); } public void Dispose() { if (context != null) { try { context.Undo(); } finally { CloseHandle(token); context = null; } } }}
Before accessing the ing disk, call this class to change the IIS running user: logonimpersonate imper = new logonimpersonate ("user-1", "123456 ");
5. before accessing the shared directory, call wnethelper. wnetaddconnection to add disk ing.
Public static bool createdirectory (string path) {uint state = 0; If (! Directory. exists ("Z:") {state = wnethelper. wnetaddconnection (@ "comp-1/user-1", "123456", @ "// 192.168.0.9/share", "Z:");} If (state. equals (0) {directory. createdirectory (PATH); Return true;} else {Throw new exception ("add network drive error, error code:" + state. tostring ());}}
6. Complete.
The concise code is:
Logonimpersonate imper = new logonimpersonate ("user-1", "123456 ");
Wnethelper. wnetaddconnection (@ "comp-1/user-1", "123456", @ "// 192.168.0.9/share", "Z :");
Directory. createdirectory (@ "Z:/newfolder ");
File1.saveas (@ "Z:/newfolder/test.jpg ");
Do not understand can send email to me: sqzhuyi@gmail.com