通过IIS文件上传机制,将文件上传到文件服务器

对于需要经常上传文件的站点,为了保证文件安全性,不会把文件上传到站点下,而是把文件上传到指定的文件服务器,这里主要讲一下通过http协议上传文件。

http协议的文件上传,我目前接触到的又有两种方式:一是IIS文件上传机制,二是跨域文件上传。

本文主要讲的是IIS文件上传机制。

1.先将文件上传到应用服务器。 HTML

ajax上传文件到文件服务器-通过IIS上传文件

JS

通过一般处理程序将文件上传到应用服务器

public string UploadImgFiles(HttpContext context)

{

HttpPostedFile files = context.Request.Files["file"];

string src = context.Request.QueryString["src"] ?? context.Request.Form["src"];

try

{

//文件上传路径+年月日

src = src + DateTime.Now.ToString("yyMMdd") + "/";

string uploadPath = context.Request.PhysicalApplicationPath + src;//获取文件在应用服务器存放的绝对路径

//判断文件上传路径文件夹是否存在

if (!Directory.Exists(uploadPath))

{

Directory.CreateDirectory(uploadPath);//创建文件夹

}

//上传文件至应用服务器

files.SaveAs(uploadPath + files.FileName);

Image pic = Image.FromFile(uploadPath + files.FileName);//图片的绝对路径

int intWidth = pic.Width;//长度像素值

int intHeight = pic.Height;//高度像素值

pic.Dispose();//释放资源

//文件HTTP路径,域名+端口+文件上传路径+文件名

string httpPath = "http://" + context.Request.Url.Host + ":" + context.Request.Url.Port + src + files.FileName;

at.ajaxDataFlag = true;

at.ajaxresult = httpPath;

at.ajaxString = uploadPath + files.FileName;//文件在应用服务器的绝对路径

}

catch (Exception ex)

{

at.ajaxDataFlag = false;

at.ajaxresult = "服务器内部错误,请联系开发人员!";

ALogOut.debug(ex.ToString());

}

return JsonConvert.SerializeObject(at);

}

2.将文件上传到文件服务器

public string UploadImgFilesServer(HttpContext context)

{

string AuthFlag = "";//认证类型,0:window身份认证,1:匿名身份认证

string AuthUser = "";//匿名身份认证特定用户名

string AuthPwd = "";//匿名身份认证特定密码

string httpurl = "";//文件上传到文件服务器的http地址

string fileurl = "";//文件在应用服务器的绝对路径

HttpPostedFile files = context.Request.Files["file"];

try

{

//将文件先上传到应用服务器

string JsonString = UploadImgFiles(context);

var result = JsonConvert.DeserializeObject>(JsonString);//反序列化获取文件上传到应用服务器的结果(json字符串存在null值,转换失败解决方案)

bool resultDataFlag = Convert.ToBoolean(result["ajaxDataFlag"].ToString());

if (resultDataFlag == false)

{

at.ajaxDataFlag = false;

at.ajaxresult = "服务器内部错误,请联系开发人员!";

return JsonConvert.SerializeObject(at);//如果文件上传到应用服务器的出错,则返回结果

}

else

{

//如果文件上传到应用服务器成功,则上传到文件服务器

fileurl = result["ajaxString"].ToString();//文件在应用服务器的绝对路径

WebClient client = new WebClient();

AuthFlag = System.Configuration.ConfigurationManager.AppSettings["AuthFlag"].ToString();//认证类型,0:window身份认证,1:匿名身份认证

httpurl = System.Configuration.ConfigurationManager.AppSettings["PhotoFileUrl"].ToString() + files.FileName;//文件上传地址(文件服务)

if (AuthFlag == "1")

{

//AuthFlag:1,匿名身份认证:当应用服务器和文件服务器不在同一台服务器时,IIS会启用匿名身份认证

if (System.Configuration.ConfigurationManager.AppSettings["AuthUser"] == null || System.Configuration.ConfigurationManager.AppSettings["AuthPwd"] == null)

{

at.ajaxDataFlag = false;

at.ajaxresult = "未配置匿名身份认证特定用户名或密码,请联系管理员!";

return JsonConvert.SerializeObject(at);

}

else

{

AuthUser = System.Configuration.ConfigurationManager.AppSettings["AuthUser"];

AuthPwd = System.Configuration.ConfigurationManager.AppSettings["AuthPwd"];

}

client.Credentials = new NetworkCredential(AuthUser, AuthPwd);//发送身份认证凭证

}

else if (AuthFlag == "0")

{

//AuthFlag:0,window身份认证:在应用服务器和文件服务器在同一台服务器时,IIS会启用window身份认证

if (System.Configuration.ConfigurationManager.AppSettings["PhotoFileHttp"] == null || System.Configuration.ConfigurationManager.AppSettings["PhotoFileIP"] == null)

{

at.ajaxDataFlag = false;

at.ajaxresult = "未配置文件服务器域名或者文件服务器IP地址,请联系管理员!";

return JsonConvert.SerializeObject(at);

}

else

{

//如果文件服务器和应用服务器发布在同一台服务器上,并且端口相同,需要给文件服务器添加一个不一样的端口,并且将文件上传的地址中的域名替换成该IP+端口的地址

string PhotoFileHttp = System.Configuration.ConfigurationManager.AppSettings["PhotoFileHttp"].ToString();

string PhotoFileIP = System.Configuration.ConfigurationManager.AppSettings["PhotoFileIP"].ToString();

httpurl = httpurl.Replace(PhotoFileHttp, PhotoFileIP);

}

client.Credentials = CredentialCache.DefaultCredentials;//发送身份认证凭证

}

else

{

at.ajaxDataFlag = false;

at.ajaxresult = "未配置身份认证类型!";

return JsonConvert.SerializeObject(at);

}

//client.Headers.Add("Content-Type", "application/form-data");//注意头部必须是form-data

client.Headers.Add("http-method", "LOCK");

client.Headers.Add("http-method", "DELETE");

client.Headers.Add("http-method", "MOVE");

client.Headers.Add("http-method", "TRACE");

Stream postStream = client.OpenWrite(httpurl, "PUT");

FileStream fs = new FileStream(fileurl, FileMode.Open, FileAccess.Read);

BinaryReader r = new BinaryReader(fs);

byte[] postArray = r.ReadBytes((int)fs.Length);

if (postStream.CanWrite)

{

postStream.Write(postArray, 0, postArray.Length);

}

else

{

at.ajaxDataFlag = false;

at.ajaxresult = "文件没有权限,请联系管理员!";

return JsonConvert.SerializeObject(at);

}

postStream.Close();

client.Dispose();

fs.Dispose();

File.Delete(fileurl);//删除上传至应用服务器的文件

}

at.ajaxDataFlag = true;

at.ajaxresult = httpurl;

}

catch (Exception ex)

{

at.ajaxDataFlag = false;

at.ajaxresult = "服务器内部错误,请联系开发人员!";

ALogOut.debug(ex.ToString());

}

return JsonConvert.SerializeObject(at);

}

2.1.window身份认证 文件上传到文件服务器时,如果应用服务器和文件服务器在同一台服务器,IIS会启用“window身份认证”。

这里会有个比较变态的问题,就是应用站点和文件服务器站点用域名发布后,默认为80端口,这时候上传文件会出现错误403,需要在文件服务器新增一个IP+端口的网站绑定,将文件域名的上传地址替换成IP+端口的地址,就可以解决这个问题。

//AuthFlag:0,window身份认证:在应用服务器和文件服务器在同一台服务器时,IIS会启用window身份认证

if (System.Configuration.ConfigurationManager.AppSettings["PhotoFileHttp"] == null || System.Configuration.ConfigurationManager.AppSettings["PhotoFileIP"] == null)

{

at.ajaxDataFlag = false;

at.ajaxresult = "未配置文件服务器域名或者文件服务器IP地址,请联系管理员!";

return JsonConvert.SerializeObject(at);

}

else

{

//如果文件服务器和应用服务器发布在同一台服务器上,并且端口相同,需要给文件服务器添加一个不一样的端口,并且将文件上传的地址中的域名替换成该IP+端口的地址

string PhotoFileHttp = System.Configuration.ConfigurationManager.AppSettings["PhotoFileHttp"].ToString();

string PhotoFileIP = System.Configuration.ConfigurationManager.AppSettings["PhotoFileIP"].ToString();

httpurl = httpurl.Replace(PhotoFileHttp, PhotoFileIP);

}

client.Credentials = CredentialCache.DefaultCredentials;//发送身份认证凭证

2.2.匿名身份认证 文件上传到文件服务器时,如果应用服务器和文件服务器在不在同一台服务器,IIS会启用“匿名身份认证”,这里主要需要对IIS进行配置。 IIS配置和常见错误解决办法:

错误401 错误原因 从IIS 7.0开始,不允许匿名写入WebDAV发布目录。具体来说,PUT,MKCOL,PROPPATCH,COPY,MOVE,DELETE和基于WebDAV的GET请求都需要身份验证。 解决方案 1.创建计算机用户,分配管理员权限,设置用于隶属于组;

2.打开IIS选中站点,进入身份验证,右键点击匿名身份验证,选择编辑,同时选择特定用户,输入刚刚添加的用户;

3.右键点击IIS发布的网站,选择编辑权限,将刚刚添加的用户分配完全控制权限;

4。点击IIS界面右侧基本设置,点击连接为,并选中特定用户,点击设置输入刚刚创建的用户名和密码;

5.设置身份认证凭证,这里的用户名、密码需要和IIS基本设置的特定用户的用户名和密码相同。

//AuthFlag:1,匿名身份认证:当应用服务器和文件服务器不在同一台服务器时,IIS会启用匿名身份认证

if (System.Configuration.ConfigurationManager.AppSettings["AuthUser"] == null || System.Configuration.ConfigurationManager.AppSettings["AuthPwd"] == null)

{

at.ajaxDataFlag = false;

at.ajaxresult = "未配置匿名身份认证特定用户名或密码,请联系管理员!";

return JsonConvert.SerializeObject(at);

}

else

{

AuthUser = System.Configuration.ConfigurationManager.AppSettings["AuthUser"];

AuthPwd = System.Configuration.ConfigurationManager.AppSettings["AuthPwd"];

}

client.Credentials = new NetworkCredential(AuthUser, AuthPwd);//发送身份认证凭证

错误405 1.选择IIS的WebDAV创作规则,

2.点击启用WebDAV

错误403 1.选择IIS的WebDAV创作规则,

2.选择添加创作规则

3.按照如图所示操作后,点击确定

错误409 文件路径不存在;

总结 优点:不会影响其他站点的文件,安全性较高; 缺点:因为需要把文件上传到应用服务器,再上传到文件服务器,相当于上传了两次,如果碰到大文件或多文件上,传效率较低。