首先,我们在web.config中做如下配置:
<httpHandlers>
<remove verb="*" path="*"/>
<add verb="GET,PUT,UNLOCK,LOCK,OPTIONS" path="*.doc,*.xml" type="Webdav.WebdavProtocolHandler,Webdav"/>
</httpHandlers>
public interface IVerbHandler
{
void Process( HttpContext context );
}
class OptionsHandler : IVerbHandler
{
#region IVerbHandler 成员
public void Process(System.Web.HttpContext context)
{
context.Response.AppendHeader("DASL", "<DAV:sql>");
context.Response.AppendHeader("DAV", "1, 2");
context.Response.AppendHeader("Public", "OPTIONS, TRACE, GET, HEAD, DELETE, PUT, POST, COPY, MOVE, MKCOL, PROPFIND, PROPPATCH, LOCK, UNLOCK, SEARCH");
context.Response.AppendHeader("Allow", "OPTIONS, TRACE, GET, HEAD, DELETE, PUT, COPY, MOVE, PROPFIND, PROPPATCH, SEARCH, LOCK, UNLOCK");
}
#endregion
}
实现对LOCK的支持:
class LockHandler : IVerbHandler { #region IVerbHandler 成员 public void Process(System.Web.HttpContext context) { context.Response.ContentType = "text/xml"; string token = Guid.NewGuid().ToString() + ":" + DateTime.Now.Ticks.ToString() ; context.Response.AppendHeader("Lock-Token", "<opaquelocktoken:" + token + ">"); string xml = @"<?xml version=""1.0""?> <a:prop xmlns:a=""DAV:""><a:lockdiscovery> <a:activelock><a:locktype><a:write/></a:locktype> <a:lockscope><a:exclusive/></a:lockscope><owner xmlns=""DAV:"">Administrator</owner><a:locktoken> <a:href>opaquelocktoken:{0}</a:href></a:locktoken> <a:depth>0</a:depth><a:timeout>Second-180</a:timeout></a:activelock></a:lockdiscovery> </a:prop>"; context.Response.Write( String.Format( xml , token ) ); context.Response.End(); } #endregion }
class UnLockHandler : IVerbHandler { #region IVerbHandler 成员 public void Process(System.Web.HttpContext context) { } #endregion }
CREATE TABLE [dbo].[Document] ( [DocumentId] [int] IDENTITY (1, 1) NOT NULL , [Name] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL , [Description] [text] COLLATE Chinese_PRC_CI_AS NULL , [CreateTime] [datetime] NULL , [Size] [int] NULL , [CreatorId] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL , [CreatorName] [char] (10) COLLATE Chinese_PRC_CI_AS NULL , [CreateYear] [int] NULL , [ContentType] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL , [DeptId] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL , [DeptName] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL , [Content] [image] NULL , [ModifyTime] [datetime] NULL , [OwnerType] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL , [TemplateAble] [bit] NULL ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] GO
[Serializable] public class Document { public Document() { } static public Document FromPostFile(System.Web.HttpPostedFile file , User user ) { Document doc = new Document(file); doc.CreateTime = DateTime.Now; doc.CreatorId = user.Id; doc.CreatorName = user.Name; doc.DeptId = user.OrgId; doc.DeptName = user.OrgName; return doc; } public Document(System.Web.HttpPostedFile file) { string[] strs = file.FileName.Split( '\\' ); this.Name = strs[strs.Length - 1]; Size = file.ContentLength; //读取文件的数据 this.Content = new byte[Size]; Stream fileDataStream = file.InputStream; fileDataStream.Read( this.Content , 0, Size ); ContentType = file.ContentType; } private int _DocumentId; /// <summary> /// 任务名 /// </summary> private string _Name; /// <summary> /// 任务描述 /// </summary> private string _Description; /// <summary> /// 报表创建时间 /// </summary> private DateTime _CreateTime = DateTime.Now ; private int _Size = 0 ; private byte[] _Data; /// <summary> /// 创建人Id /// </summary> private string _CreatorId; /// <summary> /// 创建人名 /// </summary> private string _CreatorName; private int _CreateYear; private string _ContentType; /// <summary> /// 部门ID(便于统计) /// </summary> private string _DeptId; /// <summary> /// 部门名 /// </summary> private string _DeptName; // Property DocumentId public int DocumentId { get { return _DocumentId; } set { this._DocumentId = value; } } // Property Name public string Name { get { return _Name; } set { this._Name = value; } } // Property Description public string Description { get { return _Description; } set { this._Description = value; } } // Property CreateTime public DateTime CreateTime { get { return _CreateTime; } set { this._CreateTime = value; } } private DateTime _ModifyTime = DateTime.Now; public DateTime ModifyTime { get { return _ModifyTime; } set { this._ModifyTime = value; } } // Property Size public int Size { get { return _Size; } set { this._Size = value; } } // Property Data public byte[] Content { get { return _Data; } set { this._Data = value; } } // Property CreatorId public string CreatorId { get { return _CreatorId; } set { this._CreatorId = value; } } // Property CreatorName public string CreatorName { get { return _CreatorName; } set { this._CreatorName = value; } } // Property CreateYear public int CreateYear { get { return _CreateYear; } set { this._CreateYear = value; } } // Property ContentType //application/msword //text/plain public string ContentType { get { return _ContentType; } set { this._ContentType = value; } } // Property DeptId public string DeptId { get { return _DeptId; } set { if (this._DeptId != value) this._DeptId = value; } } // Property DeptName public string DeptName { get { return _DeptName; } set { this._DeptName = value; } } private string _Type; public string OwnerType { get { return _Type; } set { this._Type = value; } } private bool _TemplateAble; /// <summary> /// 是否可以作为模版 /// </summary> public bool Templateable { get { return _TemplateAble; } set { this._TemplateAble = value; } } public override string ToString() { return Encoding.UTF8.GetString(this.Content); } public static Document FromString(string s, User user) { Document doc = new Document(); doc.CreateTime = DateTime.Now; doc.CreatorId = user.Id; doc.CreatorName = user.Name; doc.DeptId = user.OrgId; doc.DeptName = user.OrgName; doc.Content = Encoding.UTF8.GetBytes(s); doc.Size = doc.Content.Length; doc.ContentType = "text/plain"; return doc; } public static string ByteToString( byte[] bytes ) { return Encoding.UTF8.GetString( bytes ); } public static byte[] StringToByte(string s) { return Encoding.UTF8.GetBytes(s); } public string GetExtendName() { string[] arr = this.Name.Split( '.' ); if (arr.Length < 1) return ""; else return arr[ arr.Length - 1 ]; } }
public interface IWebdavDocumentHandler { Document GetDocument(int id);//获取文档数据 void ModifyDocContent(int docId, byte[] data);//修改文档内容 }
class GetHandler : IVerbHandler { #region IVerbHandler 成员 public void Process(System.Web.HttpContext context) { int id = WebdavProtocolHandler.GetDocumentId( context ); //获取到主键 IWebdavDocumentHandler docSvr = new DefaultWebdavDocumentHandler(); //修改此处代码,实现不同的数据操作逻辑,可引入工厂模式 Document doc = docSvr.GetDocument(id); if (doc == null) { context.Response.Write("文档不存在!"); return; } context.Response.Clear(); context.Response.ContentType = doc.ContentType; //下载文件名限制32字符 16 汉字 int maxlength = 15; string fileName = doc.Name; //att.FileName ; if (fileName.Length > maxlength) { fileName = "-" + fileName.Substring(fileName.Length - maxlength, maxlength); } fileName = HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8); //必须编码,不然文件名会出现乱码 context.Response.AppendHeader("Content-Disposition", "attachment;filename=" + fileName + ""); if (doc.Content != null && doc.Content.Length > 0) context.Response.BinaryWrite(doc.Content); context.Response.End(); } #endregion }
class PutHandler : IVerbHandler { #region IVerbHandler 成员 public void Process(System.Web.HttpContext context) { int docId = WebdavProtocolHandler.GetDocumentId(context); Document doc = GetDocFromInput(context.Request); doc.DocumentId = docId; IWebdavDocumentHandler docSvr = new DefaultWebdavDocumentHandler(); //修改此处代码,实现不同的数据操作逻辑,可引入工厂模式 docSvr.ModifyDocContent( doc.DocumentId , doc.Content ); } private Document GetDocFromInput(System.Web.HttpRequest request ) { Document doc = new Document(); //读取文件的数据 doc.Content = new byte[ request.ContentLength ]; doc.Size = request.ContentLength; Stream fileDataStream = request.InputStream; fileDataStream.Read( doc.Content , 0, doc.Size ); doc.ContentType = request.ContentType; return doc; } #endregion }
public class WebdavProtocolHandler : IHttpHandler { public static int GetDocumentId( HttpContext context )//按照前面确定的主键策略返回主键 { string url = context.Request.Url.ToString(); string[] arr = url.Split( '/' ); string id = arr[arr.Length - 2]; return Convert.ToInt32( id ); } public void ProcessRequest(HttpContext context) { HttpRequest Request = context.Request; context.Response.AppendHeader("OpenWebDavServer", "1.0"); string verb = Request.HttpMethod; //Log.Write(verb); IVerbHandler vh = GetVerbHandler( verb ); if( vh == null ) return ; vh.Process(context); } private IVerbHandler GetVerbHandler(string verb) { switch (verb) { case "LOCK" : return new LockHandler(); case "UNLOCK": return new UnLockHandler(); case "GET": return new GetHandler(); case "PUT": return new PutHandler(); case "OPTIONS": return new OptionsHandler(); default : return null; } } public bool IsReusable { get { return false; } } }